Java集合框架一之List,Queue,Set

目录

一 ArrayList, LinkedList,Stack, Queue常用方法介绍及实现 

1.实现Collection接口的ArrayList类的常用方法使用

 2.实现List集合的ArrayList类的特有方法

实现Collection接口的LinkedList类的常用方法

4.LinkedList中特有的方法

5.stack特有的方法

6.Queue特有的方法

二 实现List接口的类:

Vector和ArrayList的区别

三 集合和数组的区别

四 List中 remove(int index) 和 remove(Object o) 方法的区别

五 ListIterator 和 Iterator的区别

1. Iterator迭代器包含的方法有:

2. ListIterator迭代器包含的方法有:

3. 相同点

4. 不同点

六 在java集合体系的位置

1. ArrayList  

2. LinkedList

3. Stack

 4. Queue

七 Set接口

1. HashSet类

具体实现唯一性的比较过程:

覆盖hashCode()方法的原则:

重要的方法

2. LinkedHashSet

3. TreeSet

4. 小结

HashSet和TreeSet的区别

八 List和Set区别


Java集合大致可以分为Set、List、Queue和Map四种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map则代表具有映射关系的集合,Java 5 又增加了Queue体系集合,代表一种队列集合实现。

 Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序
 

一 ArrayList, LinkedList,Stack, Queue常用方法介绍及实现 

1.实现Collection接口的ArrayList类的常用方法使用

        /**
         * 使用Collection集合中的方法
         * 1. boolean add(E e) 在集合末尾添加元素
         * 2. boolean remove(Object o) 若本集合中有值与o相等的元素,则删除该元素并返回true
         * 3. void clear()  清楚本集合中所有元素,调用完方法后本集合为空
         * 4. boolean contains(Object o) 判断集合中是否包含某元素
         * 5. boolean isEmpty() 判断集合是否为空
         * 6. int size() 返回集合中的元素个数
         * 7. boolean addAll(Collection c) 将一个集合c中的所有元素添加到另一个集合中
         * 8. Object[] toArray() 返回一个包含本集合中所有元素的数组,类型为Object[]
         * 9. Iterator iterator() 迭代器,集合的专用遍历方式
         */


        List<Integer> list1 = new ArrayList<>();
        list1.add(1);  //在集合末尾添加元素
        list1.add(2);
        list1.add(3);
        list1.add(4);
        System.out.println(list1);  //[1, 2, 3, 4]

        Integer i = 4;
        boolean flag1 = list1.remove(i);   //若集合中有值和obj相等的元素,则删除该元素并返回true
        System.out.println("flag1: " + flag1);  //true
        System.out.println(list1);  //[1, 2, 3]

        boolean flag2 = list1.contains(1); //判断集合中是否包含某元素
        System.out.println("flag2: " + flag2);  //true

        boolean flag3 = list1.isEmpty();   //判断集合是否为空
        System.out.println("flag3: " + flag3);  //false

        System.out.println(list1.size());   //返回集合中的元素个数 3

        Object[] a = list1.toArray();   //返回一个包含本集合中所有元素的数组,类型为object[]
        System.out.println(a);  // [Ljava.lang.Object;@1540e19d

        //创建iterator迭代器,遍历list1集合
        Iterator<Integer> iterator = list1.iterator();
        while(iterator.hasNext()){
            int it = iterator.next();
            System.out.print(it + " ");  //1 2 3
        }
        System.out.println();

        list1.clear();
        System.out.println(list1.isEmpty());  //true
        System.out.println(list1.size());  //0

 2.实现List集合的ArrayList类的特有方法

         /**
         * 测试List特有的方法
         * 1. void add(int index,Object obj) 在指定位置添加元素
         * 2. Object remove(int index) 根据指定索引删除元素,并把删除元素返回
         * 3. Object set(int index,Object obj) 把指定索引位置的元素修改为指定的值,返回修改前的值
         * 4. int indexOf(Object o) 返回指定元素在集合中第一次出现的索引
         * 5. Object get(int index) 获取指定位置的元素
         * 6. ListIterator listIterator() 列表迭代器
         * 7. List subList(int fromIndex,int toIndex) 截取从索引fromIndex到toIndex的元素集合 包左不包右
         */
        List<Integer> list2 = new ArrayList<>();
        List<Integer> list3 = new ArrayList<>();

        list2.add(6);
        list2.add(3);
        list2.add(4);
        list2.add(5);
        list2.add(1,2);  //在指定位置插入元素,后面的元素都往后移一个元素
        System.out.println(list2);  //[6, 2, 3, 4, 5]

        list2.set(0,1);  //在索引为index位置的元素更改为obj
        System.out.println(list2);  //[1, 2, 3, 4, 5]

        int value1 = list2.remove(3);  // 删除指定索引的元素
        System.out.println("value1: " + value1); //4
        System.out.println("list2: " + list2);  //[1, 2, 3, 5]

        Integer i1 = 3;
        int value2 = list2.indexOf(i1); //返回集合中第一次出现的o元素的索引位置,如果list集合没有o元素,则返回-1
        System.out.println(value2); //2


        int i2 = list2.get(2);    //返回集合中指定索引位置的元素
        System.out.println(i2);  //3

        ListIterator<Integer> iterator1 = list2.listIterator();
        while(iterator1.hasNext()){
            System.out.print(iterator1.next()+" ");
        }
        System.out.println();

        System.out.println(list2); //[1, 2, 3, 5]
        iterator1.add(5);
        System.out.println(list2); //[1, 2, 3, 5, 5]


        while(iterator1.hasPrevious()){
            System.out.print(iterator1.previous() + " ");  //5 5 3 2 1
        }
        System.out.println();

        list3 = list2.subList(1,3);  //返回从索引fromIndex到toIndex的元素集合,包左不包右
        System.out.println(list3);   //[2, 3]

        iterator1.next();  //返回集合中Iterator指向位置后面的元素
        int i4 = iterator1.nextIndex();  //返回列表中ListIterator所需位置后面元素的索引
        System.out.println(i4);   // 1

实现Collection接口的LinkedList类的常用方法

        /**
         * 测试Collection中的方法
         * 1. boolean add(E e) 在集合末尾添加元素
         * 2. boolean remove(Object o) 若本集合中有值与o相等的元素,则删除该元素并返回true
         * 3. void clear()  清楚本集合中所有元素,调用完方法后本集合为空
         * 4. boolean contains(Object o) 判断集合中是否包含某元素
         * 5. boolean isEmpty() 判断集合是否为空
         * 6. int size() 返回集合中的元素个数
         * 7. boolean addAll(Collection c) 将一个集合c中的所有元素添加到另一个集合中
         * 8. Object[] toArray() 返回一个包含本集合中所有元素的数组,类型为Object[]
         * 9. Iterator iterator() 迭代器,集合的专用遍历方式
         */
        List<String> list1 = new LinkedList<>();
        list1.add("1");
        list1.add("2");
        list1.add("3");
        list1.add("4");
        System.out.println(list1);  //[1, 2, 3, 4]
        System.out.println(list1.contains("2")); //true
        System.out.println(list1.size()); //4
        System.out.println(list1.isEmpty());  //false
        System.out.println(list1.remove("3"));  //true
        System.out.println(list1); //[1, 2, 4]


        Iterator<String> iterator = list1.iterator();
        while(iterator.hasNext()){
            String s = iterator.next();
            System.out.print(s+" ");  //1 2 4 
        }
        System.out.println();

        Object[] objects = list1.toArray();
        System.out.println(objects);  //[Ljava.lang.Object;@1540e19d
        for (int i = 0 ;i < objects.length; i++){
            System.out.print(objects[i] + " ");  //1 2 4
        }
        System.out.println();

        list1.clear();
        System.out.println(list1.isEmpty());  //true
        System.out.println(list1.size());  //0

        System.out.println(Arrays.toString(objects));  //[1, 2, 4]

 3.实现List接口的LinkedList类的常用方法

         /**
         * 测试List中特有的方法
         * 1. void add(int index,Object obj) 在指定位置添加元素
         * 2. Object remove(int index) 根据指定索引删除元素,并把删除元素返回
         * 3. Object set(int index,Object obj) 把指定索引位置的元素修改为指定的值,返回修改前的值
         * 4. int indexOf(Object o) 返回指定元素在集合中第一次出现的索引
         * 5. Object get(int index) 获取指定位置的元素
         * 6. ListIterator listIterator() 列表迭代器
         * 7. List subList(int fromIndex,int toIndex) 截取从索引fromIndex到toIndex的元素集合 包左不包右
         */

        List<String> list2 = new LinkedList<>();
        list2.add("2");
        list2.add("3");
        list2.add("4");
        System.out.println(list2);   //[2, 3, 4]

        list2.add(0,"1");
        System.out.println(list2);  //[1, 2, 3, 4]

        String s = list2.remove(1);
        System.out.println(s);  //2
        System.out.println(list2);  //[1, 3, 4]

        list2.set(1,"1");
        System.out.println(list2);   //[1, 1, 4]

        System.out.println(list2.indexOf("1"));  //0

        System.out.println(list2.get(2));  //4

        ListIterator listIterator = list2.listIterator();
        listIterator.next();
        listIterator.next();

        while(listIterator.hasPrevious()){
            String str = (String) listIterator.previous();
            System.out.print(str + " ");  //1 1
        }
        System.out.println();

        List sub_list = new LinkedList();
        System.out.println(list2); // [1, 1, 4]
        sub_list = list2.subList(1,3);
        System.out.println(sub_list);  //[1, 4]

4.LinkedList中特有的方法

         /**
         * 测试LinkedList中的特有方法
         * 1.addFirst(E e) 在该列表开头插入指定的元素
         * 2.addLast(E e) 将指定的元素追加到此列表的末尾
         * 3.E getFirst()  返回此列表中的第一个元素
         * 4.E getLast()  返回此列表中的最后一个元素
         * 5.E removeFirst() 从此列表中删除并返回第一个元素
         * 6.E removeLast() 从此列表中删除并返回最后一个元素
         */
        LinkedList<String> list3 = new LinkedList<>();
        list3.add("2");
        list3.add("3");
        list3.add("4");
        System.out.println(list3); //[2, 3, 4]

        list3.addFirst("1");
        list3.addLast("5");
        System.out.println(list3);  //[1, 2, 3, 4, 5]

        System.out.println(list3.getFirst());  //1
        System.out.println(list3.getLast());   //5
        
        System.out.println(list3.removeFirst());  //1
        System.out.println(list3);  //[2, 3, 4, 5]
        System.out.println(list3.removeLast());   //5
        System.out.println(list3);  //[2, 3, 4]

5.stack特有的方法

        /**
         * Stack 继承了Vector,Vector实现了List接口,因此Stack拥有List的所有方法
         * stack特有的方法
         * 1. boolean empty() 判断栈是否为空
         * 2. E peek() 查看当前的栈顶元素
         * 3. E pop() 删除当前的栈顶元素,并将其作为返回值返回
         * 4. E push(E e)	添加该数据到栈顶
         * 5. int search(object o) 若是栈顶,返回1,栈顶下一个,返回2,依次增加。找不到返回-1
         */

        Stack<Integer> stack = new Stack<>();
        stack.add(1);
        stack.add(2);
        stack.push(3);
        System.out.println(stack);  //[1, 2, 3]
        System.out.println(stack.peek());  //3

        int value1 = stack.pop();
        System.out.println(value1); //3
        System.out.println(stack);  //[1, 2]
        System.out.println(stack.peek());  //2

        System.out.println(stack.isEmpty());  //false

        System.out.println(stack.search(1));  //2

6.Queue特有的方法

Queue代表的线性表中的队列,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,遵循先进先出原则(FIFO,First In First Out)。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

        /**
         * Queue是接口,Deque双端队列继承了Queue接口,Queue和Deque都不能实例化对象
         * LinkedList实现了Queue和Deque接口,可以用LinkedList实现队列的操作
         * Queue接口特有的方法
         * 1. boolean  add(E e) 添加元素到队列中,如果不违反容量限制立即执行,若无可用可用空间会抛出异常
         * 2. E element() 返回这个队列的头,但不删除
         * 3. boolean offer(E e)  将指定的元素插入到队列中,如果不违反容量限制立即执行
         * 4. E  peek()    返回队头元素,但不删除,若队列为空,则返回null
         * 5. E  poll()    返回这个队列的队头元素并删除队头元素,若队列为空,则返回null
         * 6. E  remove()  返回队头元素并删
         */
        Queue<Integer> queue = new LinkedList<>();
        queue.add(1);//用add方式添加
        queue.offer(2);//用offer添加
        queue.offer(3);
        System.out.println("队头元素:"+ queue.element());  //1
        System.out.println("队头元素:"+queue.peek());  //1
        System.out.println("删除元素:"+queue.poll());  //1
        System.out.println("删除元素:"+queue.remove());//2
        System.out.println("队头元素:"+ queue.element());  //3

二 实现List接口的类:

ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率,可以存储重复元素

Vector和ArrayList的区别

  1. Vector是线程安全的(只是加上 synchronized 关键字), ArrayList不是线程安全的,
  2. ArrayList不可以设置扩展的容量, 默认1.5倍; Vector可以设置, 默认2倍
  3. ArrayList无参构造函数中初始量为0; Vector的无参构造函数初始容量为10

适用场景分析:
1.Vector是线程同步的,所以它也是线程安全的,而ArrayList是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用ArrayList效率比较高。
2.如果集合中的元素的数目大于目前集合数组的长度时,在集合中使用数据量比较大的数据,用Vector有一定的优势。


三 集合和数组的区别

  1. 长度区别:数组固定,集合可变
  2. 内容区别:数组可以使基本的数据类型,也可以是引用类型;集合只能是引用类型
  3. 元素内容:数组只能存储同一种类型;集合可以存储不同类型(map)

四 List中 remove(int index) 和 remove(Object o) 方法的区别

  • Object remove(int index):该方法删除位于index结点处的元素
  • boolean remove(Object o):删除特定Object元素

在大多数情况下,这两种方法的使用并不会存在歧义。

但是当我们将List的泛型参数设置为Integer时,我们只能使用前一种方式删除元素,也即是按结点位置的方法删除元素。因为无论传入的参数是int 类型还是Integer类型,都只会调用remove(int index)方法,而不会调用remove(Object o)方法。


五 ListIterator 和 Iterator的区别

1. Iterator迭代器包含的方法有:

  • hasNext():如果迭代器指向位置后面还有元素,则返回 true,否则返回false
  • next():返回集合中Iterator指向位置后面的元素
  • remove():删除集合中Iterator指向位置后面的元素

2. ListIterator迭代器包含的方法有:

  • add(E e): 将指定的元素插入列表,插入位置为迭代器当前位置之前
  • hasNext():以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false
  • hasPrevious():如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false
  • next():返回列表中ListIterator指向位置后面的元素
  • nextIndex():返回列表中ListIterator所需位置后面元素的索引
  • previous():返回列表中ListIterator指向位置前面的元素
  • previousIndex():返回列表中ListIterator所需位置前面元素的索引
  • remove():从列表中删除next()或previous()返回的最后一个元素(有点拗口,意思就是对迭代器使用hasNext()方法时,删除ListIterator指向位置后面的元素;当对迭代器使用hasPrevious()方法时,删除ListIterator指向位置前面的元素)
  • set(E e):从列表中将next()或previous()返回的最后一个元素返回的最后一个元素更改为指定元素e

3. 相同点

都是迭代器,当需要对集合中元素进行遍历不需要干涉其遍历过程时,这两种迭代器都可以使用。

4. 不同点

  1. 使用范围不同,Iterator可以应用于所有的集合,Set、List和Map和这些集合的子类型。而ListIterator只能用于List及其子类型。
  2. ListIterator有add方法,可以向List中添加对象,而Iterator不能。
  3. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator不可以。
  4. ListIterator可以定位当前索引的位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
  5. 都可实现删除操作,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。

六 在java集合体系的位置

1. ArrayList  

ArrayList list = new ArrayList();

List list = new ArrayList();

ArrayList是一个类,实现了List接口,List接口有继承了Colletion接口

2. LinkedList

LinkedList list = new LinkedList();

List list = new LinkedList();

LinkedList 是一个类,实现了List接口,Deque接口(双端队列),List接口有继承了Colletion接口,Deque接口继承了Queue接口,Queue接口继承了Colletion接口

3. Stack

Stack stack = new Stack();

Stack是一个类,继承了Vector类,Vector类实现了List接口,List接口有继承了Colletion接口。

Vector 是线程安全的动态数组,同 ArrayList 一样继承自 AbstractList 且实现了 List、RandomAccess、Cloneable、Serializable 接口。
内部实现依然基于数组,Vector 与 ArrayList 基本是一致的,唯一不同的是 Vector 是线程安全的,会在可能出现线程安全的方法前面加上 synchronized 关键字。
其和 ArrayList 类似,随机访问速度快,插入和移除性能较差(数组原因),支持 null 元素,有顺序,元素可以重复,线程安全。

 4. Queue

Queue queue = new LinkedList();

Queue是作为Collection接口的一个子接口,而Deque继承了Queue接口,也就是说Deque拥有更多操作。不过需要注意的是,Queue和Deque都是接口,不能实例化对象,而LinkedList类实现了Deque接口,也就间接实现了Queue,所以我们可以用LinkedList来实现队列的操作。


七 Set接口

 Set是继承Collection接口,因此具有其所有的方法。类 HashSet和类TreeSet实现了Set接口,LinkedHashSet类继承了HashSet类,并且实现了Set接口。

1. HashSet类

底层数据结构采用哈希表实现,元素无序且唯一线程不安全效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。

具体实现唯一性的比较过程:

存储元素首先会使用hash()算法函数生成一个int类型hashCode散列值,然后和已经存储的元素的hashCode值比较。如果hashCode不相等,则所存储的两个对象一定不相等,此时存储当前的新的hashCode值处的元素对象;如果hashCode相等,存储元素的对象还是不一定相等,此时会调用equals()方法判断两个对象的内容是否相等。如果内容相等,那么就是同一个对象,无需存储;如果比较的内容不相等,那么就是不同的对象,就该存储了,此时就要采用哈希的解决地址冲突算法,在当前hashCode值处创建一个新的链表, 在同一个hashCode值的后面存储存储不同的对象,这样就保证了元素的唯一性。

Set的实现类的集合对象中不能够有重复元素,HashSet用一种算法来保证HashSet中的元素是不重复的。 HashSet采用哈希算法,底层用数组存储数据。默认初始化容量16,加载因子0.75

Object类中的hashCode()的方法是所有子类都会继承这个方法,这个方法会用Hash算法算出一个Hash(哈希)码值返回,HashSet会用Hash码值去和数组长度取模, 模(这个模就是对象要存放在数组中的位置)相同时才会判断数组中的元素和要加入的对象的内容是否相同,如果不同才会添加进去。

覆盖hashCode()方法的原则:

  1. 一定要让那些我们认为相同的对象返回相同的hashCode值
  2. 尽量让那些我们认为不同的对象返回不同的hashCode值,否则,就会增加冲突的概率。
  3. 尽量的让hashCode值散列开(两值用异或运算可使结果的范围更广)

相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成,我们应该为保存到HashSet中的对象覆盖hashCode()和equals()。

因为在将对象加入到HashSet中时,会首先调用hashCode方法计算出对象的hash值,接着根据此hash值调用HashMap中的hash方法,得到的值& (length-1)得到该对象在hashMaptransient Entry[] table中的保存位置的索引,接着找到数组中该索引位置保存的对象,并调用equals方法比较这两个对象是否相等,如果相等则不添加。

注意:要存入HashSet的集合对象中的自定义类必须覆盖hashCode(),equals()两个方法,才能保证集合中元素不重复。

在覆盖equals()和hashCode()方法时, 要使相同对象的hashCode()方法返回相同值,覆盖equals()方法再判断其内容。为了保证效率,所以在覆盖hashCode()方法时, 也要尽量使不同对象尽量返回不同的Hash码值。

如果数组中的元素和要加入的对象的hashCode()返回了相同的Hash值(相同对象),才会用equals()方法来判断两个对象的内容是否相同。

重要的方法

add(E e),添加的元素不可重复,是通过HashMap的put方法来保证的,往HashMap中put数据时,如果key是一样的,只会替换key对应的value,不会新插入一条数据。所以往HashSet中add相同的元素没有什么用,这里的相同是通过equals方法保证的。

remove(Object o), 从HashMap中移除一条数据。

还有比较总要的是size(), isEmpty(), contains(), clear()等。

注意由于Collection接口中没有get,set方法,故HashSet没有提供set(), get()方法。

2. LinkedHashSet

LinkedHashSet继承自HashSet,底层数据结构采用链表哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。唯一的区别是LinkedHashSet内部使用的是LinkHashMap。这样做的意义或者好处就是LinkedHashSet中的元素顺序是可以保证的,也就是说遍历序和插入序是一致的。

3. TreeSet

底层数据结构采用二叉树来实现,元素唯一且已经排好序

唯一性同样需要重写hashCode和equals()方法,二叉树结构保证了元素的有序性。

根据构造方法不同,分为自然排序(无参构造)和比较器排序(有参构造)。

  • 自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储。
  • 比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法。

4. 小结

Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像前面有两个不同的List

实际上Set就是Collection,只是行为不同。(这是继承与多态思想的典型应用:表现不同的行为。)

Set 存入的每个元素都必须是唯一的,加入Set的元素必须定义equals()方法以确保对象的唯一性。

HashSet和TreeSet的区别

  1. 1.TreeSet 是二差树(红黑树的树据结构)实现的,Treeset中的数据是自动排好序的,不允许放入null值。
  2. 2.HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。
  3. 3.HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例。

适用场景分析:HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。为快速查找而设计的Set,我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。


八 List和Set区别

List特点:元素有放入顺序,元素可重复,可以通过索引直接操作元素。和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉,不能根据索引获取元素。检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。

注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,加入Set 的Object必须定义equals()方法 。另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值