【问题标题】:What is the difference between Set and List?集合和列表有什么区别?
【发布时间】:2010-11-05 07:42:29
【问题描述】:

Set<E>List<E> 接口之间的根本区别是什么?

【问题讨论】:

标签: java list set


【解决方案1】:

List 是一个有序的元素序列,而Set 是一个独特的无序元素列表(谢谢Quinn Taylor)。

List<E>:

有序集合(也称为 顺序)。该界面的用户 有精确的控制在哪里 列出每个插入的元素。这 用户可以通过他们的访问元素 整数索引(列表中的位置), 并在列表中搜索元素。

Set<E>:

一个集合不包含 重复元素。更正式地说, 集合不包含元素对 e1 和 e2 使得 e1.equals(e2),并且在 最多一个空元素。正如所暗示的那样 它的名字,这个接口模拟了 数学集合抽象。

【讨论】:

  • 对于一个 SortedSet,没有两个元素 compareTo() == 0,因为 equals 没有被调用。
  • 可以订购一个集合,所以这个答案的第一个陈述是误导性的,即使当然必须选择一个列表来执行集合顺序
  • 错了!可以订购 Java 集,具体取决于实现;例如,Java TreeSet 是有序的。在 Java 的上下文中,List 和 Set 之间的唯一区别是 Set 包含唯一项。在数学的上下文中,集合中的项目是唯一且无序的。
  • 是的,Java 集可以但不是必须订购的。是的,如果你有一个 TreeSet,你可以指望它被订购。但是你必须知道你有一个 TreeSet 而不仅仅是一个 Set。如果您返回一个 Set,您不能依赖它来订购。另一方面,List 是按其性质排序的,List 的任何实现都必须排序。因此,就接口定义而言,说 Set 是无序的并不是特别错误,但说 Set 不保证元素顺序在技术上可能更正确。
  • 不要将“有序”与“排序”混为一谈。同样,不要将接口的合同和接口的实现混为一谈。说“无序”的东西没有顺序也是错误的,它只是意味着无法保证订单的执行(并且与有序列表不同,调用之间的顺序可能不稳定)。
【解决方案2】:
List Set
Duplicates Yes No
Order Ordered Depends on implementation
Position Access Yes No

【讨论】:

  • 需要注意的一点:位置访问性能很大程度上取决于底层实现,数组 vs 链表stackoverflow.com/questions/322715/…
  • 如果不按位置访问,集合如何索引? (+1 为 ASCII 表)
  • 我不喜欢阅读。这使它非常简洁明了。
【解决方案3】:

元素的有序列表(是否唯一)
符合 Java 的名为 List 的接口
可以通过索引访问

使用实现

  • 链表
  • 数组列表

唯一元素列表:
符合 Java 的名为Set的接口
不能被索引访问

使用实现

  • HashSet(无序)
  • LinkedHashSet(有序)
  • TreeSet(按自然顺序或提供的比较器排序)

SetList 两个接口都符合 Java 的名为 Collection 的接口

【讨论】:

    【解决方案4】:

    Set 不能包含重复元素,而 List 可以。列表(在 Java 中)也意味着顺序。

    【讨论】:

      【解决方案5】:
      • 列表是项目的有序分组
      • Set 是项目的无序分组,不允许重复(通常)

      从概念上讲,我们通常将允许重复的无序分组称为 Bag,而不允许重复的则称为 Set。

      【讨论】:

      • 集合不能有重复项。
      • 一些集合实现是有序的(比如LinkedHashSet,它在后台维护了一个LinkedList)。但是 Set ADT 没有排序。
      【解决方案6】:

      列表:

      Lists 通常允许重复对象。 Lists 必须是有序的,因此可以通过索引访问。

      实现类包括:ArrayListLinkedListVector

      设置:

      Sets 不允许允许重复对象。 大多数实现是无序的,但它是特定于实现的。

      实现类包括: HashSet(无序), LinkedHashSet(已订购), TreeSet(按自然顺序或提供的比较器排序)

      【讨论】:

        【解决方案7】:

        列表

        1. 是元素的有序分组。
        2. List 用于收集具有重复项的元素。
        3. 在 List 中定义了新方法 界面。

        设置

        1. 是无序的元素分组。
        2. Set 用于无重复元素的集合。
        3. Set 接口内部没有定义新方法,因此我们必须仅对 Set 子类使用 Collection 接口方法。

        【讨论】:

          【解决方案8】:

          列表:
          List 允许重复元素和空值。使用元素的相应索引易于搜索,并且它将按插入顺序显示元素。 示例:(链表)

          import java.util.*;
          
          public class ListExample {
          
           public static void main(String[] args) {
              // TODO Auto-generated method stub
          
              List<Integer> l=new LinkedList<Integer>();
              l.add(001);
              l.add(555);
              l.add(333);
              l.add(888);
              l.add(555);
              l.add(null);
              l.add(null);
          
              Iterator<Integer> il=l.iterator();
          
              System.out.println(l.get(0));
          
              while(il.hasNext()){
                  System.out.println(il.next());
              }
          
              for(Integer str : l){
                  System.out.println("Value:"+str);
              }
           }
          
          }
          

          输出:

          1
          1
          555
          333
          888
          555


          价值:1
          价值:555
          价值:333
          价值:888
          价值:555
          值:空
          值:空

          设置:
          Set 不允许任何重复元素,它允许单个 null 值。它不会保持任何顺序显示元素。只有TreeSet 将按升序显示。

          示例:(树集)

          import java.util.TreeSet;
          
          public class SetExample {
          
           public static void main(String[] args) {
              // TODO Auto-generated method stub
          
              TreeSet<String> set = new TreeSet<String>();
              try {
                  set.add("hello");
                  set.add("world");
                  set.add("welcome");
                  set.add("all");
          
                  for (String num : set) {
                      System.out.println( num);
          
                  }
                  set.add(null);
              } catch (NullPointerException e) {
                  System.out.println(e);
                  System.out.println("Set doesn't allow null value and duplicate value");
              }
          
           }
          
          }
          

          输出:

          全部
          你好
          欢迎
          世界
          java.lang.NullPointerException
          设置不允许空值和重复值

          【讨论】:

          • 这个最详细
          • 设置允许空值,但它不能存储重复的空值。所以有人可能会被您在代码示例中制作的 cmets 弄糊涂。
          【解决方案9】:

          当我们谈论 Java 接口时,为什么不看看 Javadoc 呢?!

          • List 是一个有序集合(序列),它通常允许 重复
          • A Set a 是不包含重复元素的集合,迭代 订单可以由实现来保证

          没有提到关于 Sets 缺乏顺序:这取决于实现。

          【讨论】:

          • 正确。 LinkedHashSet 包含按插入顺序排列的元素。
          • 这是一个接口,一切都取决于实现。 List.get() 可以创建一个包含 pi 前 5 位小数的文件并在某些实现中抛出 StackOverFlowException,这并不意味着您可以说“列表是可以创建文件的东西”,因为这不是接口定义的合约。文档声称 Set 是根据集合的数学概念建模的,根据定义,集合是无序的。给定代码中的集合,您不能假设它是在不违反 SOLID 原则的情况下订购的。
          • @kai,如果代码稍后依赖于排序,我通常将LinkedHashSet 保留在左侧。我只使用Set 如果我真的像使用它一样使用它,因为你不能假设底层实现是LinkedHashSet 之类的,它可能是今天,但明天代码会改变,它会失败。
          • 如果你声明了一个 LinkedHashSet,你就不是在处理一个 Set,所以声明 Set 应该如何表现几乎没有关系。我想说基于某些实现将(可能的)有序性归因于集合类似于说“Runnable 的实例有一个运行方法,旨在在某个线程上运行。它们还打开数据库连接并根据实现读取客户数据。 "当然,某些实现可能会这样做,但这不是 Runnable 接口所暗示的。
          【解决方案10】:

          这可能不是您要寻找的答案,但集合类的 JavaDoc 实际上具有很强的描述性。复制/粘贴:

          有序集合(也称为 顺序)。该界面的用户 有精确的控制在哪里 列出每个插入的元素。这 用户可以通过他们的访问元素 整数索引(列表中的位置), 并在列表中搜索元素。

          与集合不同,列表通常允许 重复元素。更正式地说, 列表通常允许成对 元素 e1 和 e2 使得 e1.equals(e2),它们通常 允许多个 null 元素,如果它们 完全允许空元素。它不是 难以想象有人可能希望 实施禁止清单 重复,通过抛出运行时 用户尝试时的异常 插入它们,但我们期望这种用法 很少见。

          【讨论】:

            【解决方案11】:

            集合是一组无序的不同对象——不允许有重复的对象。它通常使用被插入对象的哈希码来实现。 (具体实现可能会添加排序,但 Set 接口本身不会。)

            列表是一组有序的对象,其中可能包含重复项。它可以用ArrayListLinkedList等来实现。

            【讨论】:

            • 我很困惑?!在这种情况下,有序/无序意味着什么?跟升序和降序有关系吗?如果是这样,List 没有被订购 ?
            • Ordered 是指输入数据完全按照用户输入的方式排列,而 Sorted 是指输入数据按字典顺序或升序/降序排序顺序(以整数值表示)。 无序表示输入数据可能会也可能不会按照用户输入的顺序存储。
            【解决方案12】:
            Factor List Set
            Is ordered grouping elements? YES NO
            Provides positional access by index? YES NO
            Can store duplicate elements? YES NO
            Can store multiple null elements? YES NO
            Childs: ArrayList, LinkedList, Vector, and Stack HashSet and LinkedHashSet

            【讨论】:

              【解决方案13】:

              1.List允许重复值,set不允许重复

              2.List 维护您在列表中插入元素的顺序 Set 不维持秩序。 3.List是一个有序的元素序列,而Set是一个不同的无序元素列表。

              【讨论】:

                【解决方案14】:

                Java 中 List 和 Set 之间的一些值得注意的区别如下:

                1) Java 中 List 和 Set 的根本区别在于允许重复元素。 Java 中的 List 允许重复,而 Set 不允许任何重复。如果您在 Set 中插入重复项,它将替换旧值。 Java 中任何 Set 的实现都只会包含唯一的元素。

                2) Java 中 List 和 Set 的另一个显着区别是顺序。 List 是有序集合,而 Set 是无序集合。 List 维护元素的插入顺序,这意味着之前插入的任何元素都将比之后插入的任何元素的索引低。 Java 中的 Set 不维护任何顺序。虽然 Set 提供了另一种称为 SortedSet 的替代方法,它可以按照特定的排序顺序存储 Set 元素,该排序顺序由存储在 Set 中的对象的 Comparable 和 Comparator 方法定义。

                3) List 接口在 Java 中的流行实现包括 ArrayList、Vector 和 LinkedList。而 Set 接口的流行实现包括 HashSet、TreeSet 和 LinkedHashSet。

                很明显,如果您需要维护插入顺序或对象,并且您的集合可以包含重复项,那么 List 是一种方法。另一方面,如果您的要求是保持没有任何重复的唯一集合,那么 Set 是可行的方法。

                【讨论】:

                • 嗨@Vibha,如果我想要这两种情况?我的意思是我不希望我的数据包含重复项,我也希望它是有序的。
                【解决方案15】:

                列表与集合

                1) Set 不允许重复。列表允许重复。在Set的实现的基础上,还维护了插入Order。

                例如:LinkedHashSet。它维护插入顺序。请参考click here

                2) 包含方法。根据 Set 的性质,它将提供更好的访问性能。最好的情况是 o(1)。但是 List 在调用contains 时存在性能问题。

                【讨论】:

                  【解决方案16】:

                  ListSet都是接口。它们都扩展了 Collection 接口。集合和列表之间的重要区别是:

                  1. 重复对象

                  ListSet 的主要区别在于 List 允许重复而 Set 不允许重复。

                  1. 订购

                  List 是一个有序集合,它维护插入顺序,这意味着在显示列表内容时,它将以元素插入列表的相同顺序显示元素。

                  Set 是一个无序集合,它不维护任何顺序。很少有 Set 实现保持顺序,例如 LinkedHashSet (它保持插入顺序中的元素)。

                  1. 空元素

                  List 允许任意数量的 null 元素集合最多只能有一个空元素

                  【讨论】:

                  • 欢迎来到 Stack Overflow!请注意,您正在回答一个非常古老且已经回答的问题。这是How to Answer 的指南。
                  【解决方案17】:

                  所有List 类都保持插入顺序。他们根据性能和其他特性使用不同的实现(例如,ArrayList 用于特定索引的访问速度,LinkedList 用于简单地维护顺序)。由于没有密钥,因此允许重复。

                  Set 类不维护插入顺序。它们可以选择性地强加一个特定的顺序(如SortedSet),但通常具有基于一些散列函数的实现定义的顺序(如HashSet)。由于Sets 是按键访问的,所以不允许重复。

                  【讨论】:

                  • Maps 通过键存储对象,但使用与对象相关的唯一值设置存储对象,通常是其哈希码。 (地图也可以使用哈希码来检查键的唯一性,但它们不是必需的。)
                  【解决方案18】:

                  最大的不同是基本概念。

                  SetList界面。 集合是数学概念。 Set 方法扩展了集合。但不添加新方法。 size() 表示基数(更多是BitSet.cardinality,Linear counter,Log Log,HyperLogLog)。 addAll() 表示联合。 retainAll() 表示交集。 removeAll() 表示差异。

                  但是列表缺少这些概念。 List 增加了很多方法来支持 Collection 接口不提供的序列概念。核心概念是INDEX。像 add(index,element),get(index),search(indexOf()),remove(index) 元素。 List 还提供“Collection ViewsubList设置没有视图。没有位置访问权限。 ListCollections 类中也提供了很多算法。排序(列表),二进制搜索(列表),反向(列表),洗牌(列表),填充(列表)。方法params是List接口。重复的元素只是概念的结果。不是本质的区别。

                  所以本质上的区别是概念。 集合是数学集合概念。列表是序列概念。

                  【讨论】:

                    【解决方案19】:

                    排序...列表有顺序,集合没有。

                    【讨论】:

                    • Set ADT 不指定排序,但某些 Set 实现(如 LinkedHashSet)保持插入顺序。
                    • 然而,更重要的区别是集合不允许重复。一个袋子/多件套就可以了。
                    • 一个 TreeSet 有顺序。
                    【解决方案20】:

                    列表:

                    1. 允许重复。
                    2. 按分组元素排序。(换句话说,有明确的顺序。不需要按升序排序)

                    设置:

                    1. 不允许重复。
                    2. 在分组元素中无序。(换句话说,没有明确的顺序。它可能按升序排列,也可能不按升序排列)

                    【讨论】:

                      【解决方案21】:

                      Set&lt;E&gt;List&lt;E&gt; 都用于存储E 类型的元素。不同之处在于Set 以无序方式存储,不允许重复值。 List 用于以有序的方式存储元素,它确实允许重复值。

                      Set 元素不能通过索引位置访问,List 元素可以通过索引位置访问。

                      【讨论】:

                      • @BalusC 请不要在没有看到发布日期的情况下发表评论。看当时值得发的帖子。
                      【解决方案22】:

                      设置: Set 的集合中不能有 Duplicate 元素。它也是一个无序的集合。要从 Set 中访问数据,只需要使用 Iterator,并且不能使用基于索引的检索。主要用于需要唯一性集合的时候。

                      列表: List 可以有重复的元素,在插入时具有自然顺序。 因此,可以根据索引或迭代器检索数据。广泛用于存储需要基于索引访问的集合。

                      【讨论】:

                        【解决方案23】:

                        你好 已经给出了很多答案..让我指出一些到目前为止没有提到的点:

                        • 大多数 List 实现(ArrayList、Vector)实现了RandomAccess 接口,这是一个用于更快访问的标记接口。没有一个 Set 实现这样做。
                        • List 使用一个名为ListIterator 的特殊迭代器支持双向迭代。 Set 使用 Iterator,它只支持一种方式迭代
                        • HashSet 比 ArrayList 占用 5.5 倍以上的内存 用于存储 相同数量的元素。

                        【讨论】:

                        • @smurti 这有点晚了,我不确定你是否注意到了,但你的第一点自相矛盾:“大多数 List 实现(ArrayList,Vector)实现 RandomAccess ...”和“...没有一个 List 实现这样做”
                        【解决方案24】:

                        这里有一个 groovy 的清晰示例。我创建了一个集合和一个列表。 然后我尝试在每个列表中存储 20 个随机生成的值。生成的值可以在 0 到 5 的范围内

                        s = [] as Set
                        l = []
                        
                        max = 5
                        print "random Numbers :"
                        20.times{
                        e = (int)Math.random()*max
                        s << e
                        l << e
                        print "$e, "
                        }
                        
                        
                        println "\n"
                        println "Set : $s "
                        println "list : $l
                        

                        结果:

                        随机数:4, 1, 4, 0, 1, 2, 4, 0, 0, 3, 4, 3, 2, 0, 4, 0, 1, 3, 1, 3

                        设置:[4, 1, 0, 2, 3]

                        列表:[4, 1, 4, 0, 1, 2, 4, 0, 0, 3, 4, 3, 2, 0, 4, 0, 1, 3, 1, 3]

                        可以看出区别在于:

                        • 设置不允许重复值。
                        • 列表允许重复值。

                        【讨论】:

                        • 列表也保持顺序。
                        【解决方案25】:

                        主题名称:列表 VS 集合

                        我刚刚浏览了 Java 最重要的主题,称为集合框架。我想和你分享我对收藏的小知识。 List、Set、Map是其中最重要的话题。那么让我们从 List 和 Set 开始吧。

                        List和Set的区别:

                        1. List 是一个扩展 AbstractList 类的集合类,其中 Set 是一个扩展 AbstractSet 类但都实现 Collection 接口的集合类。

                        2. List 接口允许重复值(元素),而 Set 接口不允许重复值。如果 Set 中有重复元素,它会替换旧值。

                        3. List 接口允许 NULL 值,而 Set 接口不允许 Null 值。如果在 Set 中使用 Null 值,它会给出NullPointerException

                        4. List 接口维护插入顺序。这意味着我们在 List 中添加元素的方式与使用迭代器或 for-each 样式获取元素的方式相同。而Set 实现不一定保持插入顺序。 (虽然SortedSet 使用TreeSet,而LinkedHashSet 维护插入顺序)。

                        5. List 接口定义了自己的方法,而 Set 接口没有自己的方法,因此 Set 仅使用 Collection 接口方法。

                        6. List 接口有一个名为 Vector 的遗留类,而 Set 接口没有任何遗留类

                        7. 最后但并非最不重要... listIterator() 方法只能用于循环遍历 List Classes 中的元素,而我们可以使用 iterator() 方法访问 Set 类元素

                          李>

                        我们还能补充什么吗?请告诉我。

                        谢谢。

                        【讨论】:

                        • 首先,ListSet 是接口,它们也具有抽象类(您提到的)形式的“基础”实现。此外,#3 完全不准确,因为大多数集合允许空值(但取决于实现)。我不明白#5 和#7,对于#6,Vector 不是遗留的,只是同步的,除非需要同步,否则不推荐使用。
                        【解决方案26】:

                        设置:

                        不能有重复的值 订购取决于实施。默认情况下不排序 无法通过索引访问

                        列表:

                        可以有重复的值 默认下单 可以通过索引访问

                        【讨论】:

                          猜你喜欢
                          • 2012-09-03
                          • 1970-01-01
                          • 2020-07-23
                          • 2013-11-19
                          • 2010-11-08
                          • 2017-12-03
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多