Set和List有什么区别?


Answers:


504

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

List<E>:

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

Set<E>:

不包含重复元素的集合。更正式地讲,集合不包含元素对e1和e2,使得e1.equals(e2)最多包含一个空元素。顾名思义,此接口对数学集合抽象进行建模。


7
对于SortedSet,没有两个元素compareTo()== 0,因为不调用equals。
彼得·劳瑞

34
A设置可以订购,所以这个答案的第一个语句是误导,即使当然列表必须选择去执行收集订单
塞缪尔EUSTACHI

24
错误!可以根据实现对Java集进行排序。例如,订购了Java TreeSet。在Java上下文中,列表和集合之间的唯一区别是集合包含唯一项。在数学的上下文中,集合的项是唯一且无序的。
stackoverflowuser2010

44
是的,没有必要订购Java Set,但是可以订购。是的,如果您有TreeSet,则可以依靠该订单。但是您必须知道您有一个TreeSet而不是Set。如果返回了Set,则不能依赖于要订购的Set。另一方面,列表是按其性质排序的,并且必须对列表的任何实现进行排序。因此,就接口定义而言,说一个Set是无序的并不是特别错误,但是说一个Set不提供元素顺序的保证在技术上可能更正确一些。
Spanky Quigman

14
不要将“排序”与“排序”混为一谈。同样,不要混淆接口的约定和接口的实现。说“无序”的东西没有顺序也是错误的,它只是意味着不能保证该顺序的执行(并且在调用之间顺序可能不稳定,这与有序列表不同)。
lilbyrdie 2014年

223
╔═══════════════════╦══════════════════════╦═════════════════════════════╗
                            List                     Set              
╠═══════════════════╬══════════════════════╬═════════════════════════════╣
     Duplicates              YES                     NO               
╠═══════════════════╬══════════════════════╬═════════════════════════════╣
       Order              ORDERED          DEPENDS ON IMPLEMENTATION  
╠═══════════════════╬══════════════════════╬═════════════════════════════╣
 Positional Access          YES                      NO                
╚═══════════════════╩══════════════════════╩═════════════════════════════╝

2
有一点需要注意:定位存取性能取决于底层实现了很多,阵列VS链表stackoverflow.com/questions/322715/...
克里斯托夫鲁西研究所

1
如果不通过位置访问,如何索引集?(对于ASCII表为+1)
tplive

72

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

实现使用

  • 链表
  • 数组列表

独特的元素列表:
顺应名为Java的接口Set
可以通过索引访问

实现使用

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

这两种接口SetList符合Java的接口命名Collection


28

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


16
  • 列表是项目的有序分组
  • 集合是一组无序的项目,不允许重复(通常)

从概念上讲,我们通常将无序分组称为允许重复的袋,将不允许重复的分组称为集合。


集合不能重复。
karim79 2009年

某些集合实现是有序的(例如LinkedHashSet,它在后台维护一个LinkedList)。但是Set ADT没有排序。
Michael Myers

10

清单

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

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

10

清单:

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

实现类包括:ArrayListLinkedListVector

组:

Set就做允许重复的对象。大多数实现都是无序的,但是它是特定于实现的。

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


7

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

  • A List是有序集合(序列),通常允许重复
  • 一个Set一个的集合,不包含重复元素,迭代顺序可以通过实施保障

没有提及关于集合的缺乏顺序:这取决于实现。


2
正确。LinkedHashSet包含按插入顺序排列的元素。
ggb667 2013年

这是一个接口,一切都取决于实现。List.get()可以创建一个包含pi的前5个小数的文件,并在某些实现中引发StackOverFlowException,这并不意味着您可以说“列表可以创建文件”,因为这不属于文件的一部分。接口定义的合同。文档声称Set是根据集合的数学概念建模的,而集合的数学概念按定义是无序的。在您的代码中给定了一个集合,您不能认为它在不违反SOLID原则的情况下是有序的。
萨拉2015年

@kai,LinkedHashSet如果代码依赖以后的排序,我通常会保留在左侧。我只Set在我真的像一个人一样使用它的情况下使用,因为您不能假定基础实现是a LinkedHashSet或诸如此类,可能是今天,但是明天代码会更改,它将失败。
Christophe Roussy

如果声明一个LinkedHashSet,则不涉及Set,因此,声明Set的行为方式几乎没有关系。我要说的是,根据某些实现将(可能的)有序性归因于集合,就像说“ Runnable实例具有要在某个线程上运行的run方法。而且,它们会打开DB连接并根据实现读取客户数据。 ” 当然,某些实现可以做到这一点,但这不是Runnable接口所隐含的。
sara 2015年

5

这可能不是您要找的答案,但是collections类的JavaDoc实际上是描述性的。复制/粘贴:

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

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


5

集合是一组无序的不同对象-不允许重复的对象。通常使用插入对象的哈希码来实现。(特定的实现可能会增加顺序,但Set接口本身不会。)

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


1
我很困惑😕!在这种情况下,有序/无序意味着什么?它与升序和降序有关吗?如果是这样,List则不下令😕–
malhobayyeb

4
排序是指输入数据完全按照用户输入的顺序排列,而排序是指按字典顺序或升序/降序(按整数值)对输入数据进行排序时。无序表示输入数据可以或可以不按照用户输入的顺序存储。
阿基尔

5

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

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
null
null
值:1
值:555
值:333
值:888
值:555
值:null
值:null

Set:
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
设置不允许空值和重复值


3

1.列表允许重复的值并且设置不允许重复

2.List保持将元素插入列表的顺序Set不保持顺序。3.List是元素的有序序列,而Set是元素的无序列表。


3

清单与集合

1)设置不允许重复。列表允许重复。基于Set的实现,它还维护插入Order。

例如:LinkedHashSet。它保持插入顺序。请参考单击此处

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


2

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

这些Set类不保持插入顺序。它们可以可选地强加特定的顺序(如SortedSet),但通常具有基于某种哈希函数的实现定义的顺序(如HashSet)。由于Sets是通过密钥访问的,因此不允许重复。


地图按键存储对象,但使用与对象相关的唯一值(通常是其哈希码)设置存储对象。(地图也可以使用哈希码来检查键的唯一性,但并非必须如此。)
Quinn Taylor 2009年


1

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

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

2) Java中List和Set之间的另一个重要区别是顺序。List是有序集合,而Set是无序集合。List保持元素的插入顺序,这意味着之前插入的任何元素的索引都比后面插入的任何元素的索引低。用Java设置不会保持任何顺序。尽管Set提供了另一个称为SortedSet的替代方法,它可以按Set中存储的Object的Comparable和Comparator方法定义的特定排序顺序存储Set元素。

3) Java中List接口的流行实现包括ArrayList,Vector和LinkedList。虽然Set接口的流行实现包括HashSet,TreeSet和LinkedHashSet。

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


嗨@Vibha,如果我要同时满足这两个条件?我的意思是我不希望我的数据包含重复项,而且我也希望它是有序的。
潘纳多(Panadol Chong)

1

清单:

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

组:

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

0

Set<E>List<E>都用于存储type的元素E。区别在于,它们Set以无序方式存储,并且不允许重复值。List用于以有序方式存储元素,并且确实允许重复值。

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


1
@BalusC请不要在未看到发布日期的情况下发表评论。看到当时值得的帖子。
Yash

0

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

  • 大多数List实现(ArrayList,Vector)实现RandomAccess接口,该接口是用于更快访问的标记接口。Set实现均不这样做。
  • List使用了一个特殊的Iterator ListIterator ,它支持双向迭代。Set使用Iterator,它仅支持1路迭代
  • HashSet占用的内存比ArrayList 多5.5倍,用于存储相同数量的元素。

@smurti,这有点晚了,不确定您是否已注意,但是您的第一点与自己矛盾:“大多数List实现(ArrayList,Vector)实现RandomAccess ...”和“ ... None of the List实施做到这一点”
Peter M

0

最大的不同是基本概念。

设置列表界面。集合是数学概念。设置方法扩展了collection。但是不添加新方法。size()表示基数(更多是BitSet.cardinality,线性计数器,Log Log,HyperLogLog)。addAll()表示并集。keepAll()表示交集。removeAll()表示差异。

但是,列表缺少这些概念。列表添加了很多方法来支持Collection接口不提供的序列概念。核心概念是INDEX。例如add(index,element),get(index),search(indexOf()),remove(index)元素。列表还提供“ 集合视图 ”子列表设置没有视图。没有位置访问权限。List还提供了Collections类中的很多算法。sort(列表),binarySearch(列表),reverse(列表),shuffle(列表),fill(列表)。方法参数是List接口。重复元素只是概念的结果。不是本质的区别。

因此,本质区别在于概念。集合是数学集合的概念。列表是序列概念。


-1

这是一个时髦的例子。我创建一个集合和一个列表。然后我尝试在每个列表中存储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]

您可以看到不同之处在于:

  • 设置不允许重复的值。
  • 列出允许重复的值。

1
列表也保持排序。
glen3b

-1

像答案一样,SET没有重复的值,List可以。当然,区分它们是另一回事。


-1

Set: Set的集合中不能包含Duplicate元素。它也是一个无序集合。要从Set中访问数据,需要仅使用Iterator,并且不可能基于索引的检索。它主要在需要唯一性收集时使用。

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


-2

主题名称:List VS Set

我刚刚讲了Java最重要的主题,即Collections Framework。我想与您分享我对收藏的一点知识。列表,集合,地图是其中最重要的主题。因此,让我们从列表和设置开始。

列表和集合之间的区别:

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

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

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

  4. 列表界面保持插入顺序。这意味着我们使用迭代器或for-each样式获取列表中元素的方式与添加列表中元素的方式相同。然而,Set实现不一定必须保持插入顺序。(尽管SortedSet使用TreeSet,并LinkedHashSet保持插入顺序)。

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

  6. 列表接口有一个旧类,Vector而设置接口没有任何旧类

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

我们还能添加什么吗?请告诉我。

谢谢。


例如,ListSet是接口,它们也具有抽象类形式的“基本”实现(您已提到)。另外,#3 完全不准确,因为大多数设置都允许空值(但取决于实现)。我不了解#5和#7,并且#6 Vector不是旧版,而是仅同步的,除非需要同步,否则不推荐使用。
glen3b

-3

组:

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

清单:

可以有重复值默认情况下可以排序通过索引可以访问

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.