JAVA集合框架 一:Collection(LIst,Set)和Iterator(迭代器)

目录

一、Java 集合框架体系 

1.Collection接口:用于存储一个一个的数据,也称单列数据集合(single)。

2.Map接口:用于存储具有映射关系“key-value对”的集合(couple)

3.Iterator接口:不提供存储对象的能力,主要用于遍历Collection中的元素

二、Iterator(迭代器)接口

1.常用方法

 2.foreach循环

三、Collection接口及方法

1.添加方法

2.判断方法

3.删除方法

4.其他方法

四、 Collection子接口1:List

 1.List接口特点

 2.List接口方法

3.List接口主要实现类之一:ArrayList

4.List的实现类之二:LinkedList

5.List的实现类之三:Vector

五、Collection子接口2:Set

详解(如果你有疑问,可跳转到另一篇文章查看)

1.Set接口概述

2.Set主要实现类:HashSet

HashSet概述:

 方法:

示例:

3.Set主要实现类二:LinkedHashSet

与HashSet相比,LinkedHashSet有以下特点:

 4.Set实现类之三:TreeSet

1.TreeSet概述

 常用方法:

六、总结

List接口的实现类特点:

Set接口的实现类特点:


下一篇:Map接口及子实现类,Collections工具类

一、Java 集合框架体系 

1.Collection接口:用于存储一个一个的数据,也称单列数据集合(single)

  • List子接口:用来存储有序的、可以重复的数据(主要用来替换数组,"动态"数组)

    • 实现类:ArrayList(主要实现类)、LinkedList、Vector

  • Set子接口:用来存储无序的、不可重复的数据(类似于高中讲的"集合")

    • 实现类:HashSet(主要实现类)、LinkedHashSet、TreeSet

2.Map接口:用于存储具有映射关系“key-value对”的集合(couple)

  • HashMap(主要实现类)、LinkedHashMap、TreeMap、Hashtable、Properties

3.Iterator接口:不提供存储对象的能力,主要用于遍历Collection中的元素

二、Iterator(迭代器)接口

1.常用方法

方法 描述
public Iterator iterator() 获取集合对应的迭代器,用来遍历集合中的元素
public E next() 返回迭代的下一个元素
public boolean hasNext() 如果仍有元素可以迭代,则返回 true
void remove() 从集合中删除迭代器返回的最后一个元素(可选操作)
List list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("orange");

Iterator iterator = list.iterator(); // 获取迭代器

while(iterator.hasNext()) {
    String element = iterator.next(); // 获取下一个元素
    System.out.println(element);
}

输出:

apple

banana

orange 

 2.foreach循环

  • foreach循环的语法格式: 

for(元素的数据类型 局部变量 : Collection集合或数组){ 
  	//操作局部变量的输出操作
}
//这里局部变量就是一个临时变量,自己命名就可以
  • 对于集合的遍历,增强for的内部原理其实是个Iterator迭代器。如下图。

当编译器遇到增强for循环时,会自动生成一个与该集合对应的迭代器,并使用迭代器来迭代集合中的元素。在每次循环中,编译器会自动调用迭代器的next()方法获取下一个元素,并将其赋值给element变量。当集合中没有更多元素时,迭代器的hasNext()方法会返回false,循环结束。

JAVA集合框架 一:Collection(LIst,Set)和Iterator(迭代器)_第1张图片

  •  它用于遍历Collection和数组。通常只进行遍历元素,不能在遍历的过程中对集合元素进行增删操作。
public class Test {
    public static void main(String[] args) {
        String[] str ={"aa","bb", "cc", "dd", "ee"};
        for (String myStr : str) {
            myStr = "wrong";
            System.out.println(myStr);
        }
        for (int i = 0; i < str.length; i++) {
            System.out.println(str[i]);
        }
    }
}

wrong
wrong
wrong
wrong
wrong
aa
bb
cc
dd
ee 

三、Collection接口及方法

1.添加方法

add(E obj) 添加元素对象到当前集合中
addAll(Collection other) 添加other集合中的所有元素对象到当前集合中,即this = this ∪ other
public class Test {
    public static void main(String[] args) {
        testAdd();
        testAddAll();
    }
    public static void testAdd(){
        //ArrayList是Collection的子接口List的实现类之一。
        //因为Collection是一个接口,而不是一个具体的类,不能直接被实例化。在Java中,接口是一种抽象类型,只定义了接口的方法声明,而没有具体的实现。
        //因此,我们不能通过"new Collection()"来创建一个Collection对象。
        //相反,ArrayList是Collection接口的一个具体实现类,它提供了对一个动态大小的数组的操作方法。
        //所以,我们可以使用"new ArrayList()"来创建一个ArrayList对象,并将其赋值给Collection类型的变量coll。
        //可以根据需要选择不同的类作为接口的实现类,因为接口可以有多个实现类
        Collection coll = new ArrayList();
        coll.add("486");
        coll.add("艾米莉亚");
        coll.add("蕾姆");
        System.out.println(coll);
    }
    public static void testAddAll(){
        Collection c1 = new ArrayList();
        c1.add(1);
        c1.add(2);
        System.out.println("c1集合元素的个数:" + c1.size());//2
        System.out.println("c1 = " + c1);

        Collection c2 = new ArrayList();
        c2.add(1);
        c2.add(2);
        System.out.println("c2集合元素的个数:" + c2.size());//2
        System.out.println("c2 = " + c2);

        Collection other = new ArrayList();
        other.add(1);
        other.add(2);
        other.add(3);
        System.out.println("other集合元素的个数:" + other.size());//3
        System.out.println("other = " + other);
        System.out.println();

        c1.addAll(other);
        System.out.println("c1集合元素的个数:" + c1.size());//5
        System.out.println("c1.addAll(other) = " + c1);

        c2.add(other);
        System.out.println("c2集合元素的个数:" + c2.size());//3
        System.out.println("c2.add(other) = " + c2);
    }
}

 输出:

[486, 艾米莉亚, 蕾姆]
c1集合元素的个数:2
c1 = [1, 2]
c2集合元素的个数:2
c2 = [1, 2]
other集合元素的个数:3
other = [1, 2, 3]

c1集合元素的个数:5
c1.addAll(other) = [1, 2, 1, 2, 3]
c2集合元素的个数:3
c2.add(other) = [1, 2, [1, 2, 3]]

JAVA集合框架 一:Collection(LIst,Set)和Iterator(迭代器)_第2张图片

2.判断方法

方法名 方法描述
int size() 获取当前集合中实际存储的元素个数
boolean isEmpty() 判断当前集合是否为空集合
boolean contains(Object obj) 判断当前集合中是否存在一个与obj对象equals返回true的元素
boolean containsAll(Collection coll) 判断coll集合中的元素是否在当前集合中都存在。即coll集合是否是当前集合的“子集”
boolean equals(Object obj) 判断当前集合与obj是否相等

区分: contains与 containsAll

public class Test {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add(1);
        c1.add(2);
        System.out.println("c1集合元素的个数:" + c1.size());//2
        System.out.println("c1 = " + c1);

        Collection c2 = new ArrayList();
        c2.add(1);
        c2.add(2);
        System.out.println("c2集合元素的个数:" + c2.size());//2
        System.out.println("c2 = " + c2);

        Collection other = new ArrayList();
        other.add(1);
        other.add(2);
        other.add(3);
        System.out.println("other集合元素的个数:" + other.size());//3
        System.out.println("other = " + other);
        System.out.println();

        c1.addAll(other);
        System.out.println("c1集合元素的个数:" + c1.size());//5
        System.out.println("c1.addAll(other) = " + c1);
        System.out.println("c1.contains(other) = " + c1.contains(other));
        System.out.println("c1.containsAll(other) = " + c1.containsAll(other));
        System.out.println();

        c2.add(other);
        System.out.println("c2集合元素的个数:" + c2.size());
        System.out.println("c2.add(other) = " + c2);
        System.out.println("c2.contains(other) = " + c2.contains(other));
        System.out.println("c2.containsAll(other) = " + c2.containsAll(other));
    }
}

输出:

c1集合元素的个数:2
c1 = [1, 2]
c2集合元素的个数:2
c2 = [1, 2]
other集合元素的个数:3
other = [1, 2, 3]

c1集合元素的个数:5
c1.addAll(other) = [1, 2, 1, 2, 3]
c1.contains(other) = false
c1.containsAll(other) = true

c2集合元素的个数:3
c2.add(other) = [1, 2, [1, 2, 3]]
c2.contains(other) = true
c2.containsAll(other) = false

3.删除方法

方法 描述
void clear() 清空集合元素
boolean remove(Object obj) 从当前集合中删除第一个找到的与obj对象equals返回true的元素
boolean removeAll(Collection coll) 从当前集合中删除所有与coll集合中相同的元素。即this = this - this ∩ coll
boolean retainAll(Collection coll) 从当前集合中删除两个集合中不同的元素,使得当前集合仅保留与coll集合中的元素相同的元素,即当前集合中仅保留两个集合的交集,即this = this ∩ coll;

区别 :removeAll和retainAll

public class Test {
    public static void main(String[] args) {
        Collection coll = new ArrayList();
        coll.add("486");
        coll.add("艾米莉亚");
        coll.add("蕾姆");
        coll.add("拉姆");
        System.out.println("coll = " + coll);

        Collection other = new ArrayList();
        other.add("艾米莉亚");
        other.add("蕾姆");
        other.add("拉姆");
        System.out.println("other = " + other);

        coll.retainAll(other);
        System.out.println("coll.retainAll(other)之后,coll = " + coll);
        System.out.println("coll.retainAll(other)之后,other = " + other);
        System.out.println();

        Collection coll1 = new ArrayList();
        coll1.add("486");
        coll1.add("艾米莉亚");
        coll1.add("蕾姆");
        coll1.add("拉姆");
        System.out.println("coll1 = " + coll1);

        Collection other1 = new ArrayList();
        other1.add("艾米莉亚");
        other1.add("蕾姆");
        other1.add("拉姆");
        System.out.println("other1 = " + other1);

        coll1.removeAll(other1);
        System.out.println("coll1.removeAll(other1)之后,coll1 = " + coll1);
        System.out.println("coll1.removeAll(other1)之后,other1 = " + other1);
    }
}

 输出:

coll = [486, 艾米莉亚, 蕾姆, 拉姆]
other = [艾米莉亚, 蕾姆, 拉姆]
coll.retainAll(other)之后,coll = [艾米莉亚, 蕾姆, 拉姆]
coll.retainAll(other)之后,other = [艾米莉亚, 蕾姆, 拉姆]

coll1 = [486, 艾米莉亚, 蕾姆, 拉姆]
other1 = [艾米莉亚, 蕾姆, 拉姆]
coll1.removeAll(other1)之后,coll1 = [486]
coll1.removeAll(other1)之后,other1 = [艾米莉亚, 蕾姆, 拉姆]

4.其他方法

方法名 功能描述
toArray() 返回包含当前集合中的一个Object[]类型的数组(集合转数组)
toArray(T[] a) 将集合转换为指定类型的数组,并将集合元素存储到指定的数组中。
asList() 数组转集合
hashCode() 获取集合对象的哈希值
iterator() 返回迭代器对象,用于集合遍历
public class Test {
    public static void main(String[] args) {
        System.out.println("集合转数组遍历1:");
        Collection list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        Object[] str = list.toArray();
        for (Object s: str
             ) {
            System.out.println(s);
        }

        System.out.println("集合转数组遍历2:");
        String[] str2 = new String[list.size()];
        String[] array = list.toArray(str2);
        for (String s: array) {
            System.out.println(s);
        }

        System.out.println("数组转集合迭代器遍历:");
        String[] str1 = {"dd","ee","ff"};
        Collection list1 = Arrays.asList(str1);
        Iterator iterator = list1.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

 集合转数组遍历1:
aaa
bbb
ccc
集合转数组遍历2:
aaa
bbb
ccc
数组转集合迭代器遍历:
dd
ee
ff

四、 Collection子接口1:List

 1.List接口特点

  • 鉴于Java中数组用来存储数据的局限性,我们通常使用java.util.List替代数组

  • List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引(从0开始)。

 2.List接口方法

功能 方法 描述
插入元素 void add(int index, Object ele) 在index位置插入ele元素
boolean addAll(int index, Collection eles) 从index位置开始将eles中的所有元素添加进来
获取元素 Object get(int index) 获取指定index位置的元素
List subList(int fromIndex, int toIndex) 返回从fromIndex到toIndex位置的子集合
获取元素索引 int indexOf(Object obj) 返回obj在集合中首次出现的位置
int lastIndexOf(Object obj) 返回obj在当前集合中末次出现的位置
删除和替换元素 Object remove(int index) 移除指定index位置的元素,并返回此元素
Object set(int index, Object ele) 设置指定index位置的元素为ele

3.List接口主要实现类之一:ArrayList

  • ArrayList 是 List 接口的主要实现类

  • 本质上,ArrayList是对象引用的一个”变长”数组,允许重复和空元素

  • 当添加或删除元素时,ArrayList会自动调整数组的大小以容纳新的元素或释放对应的空间。

  • Arrays.asList(…) 方法返回的 List 集合,既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…) 返回值是一个固定长度的 List 集合

ArrayList方法:ArrayList (Java SE 11 & JDK 11 ) (runoob.com)

4.List的实现类之二:LinkedList

  • 实现了List接口和Deque接口,对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高。这是由底层采用链表(双向链表)结构存储数据决定的。

  •  LinkedList方法:LinkedList (Java SE 11 & JDK 11 ) (runoob.com)

        特有方法:

方法名 功能描述 返回值类型
addFirst(Object obj) 将指定的元素作为列表的第一个元素插入。如果列表为空,则该元素也将成为最后一个元素。 void
addLast(Object obj) 将指定的元素作为列表的最后一个元素插入。如果列表为空,则该元素也将成为第一个元素。 void
getFirst() 返回列表中的第一个元素,但不会移除它。 Object
getLast() 返回列表中的最后一个元素,但不会移除它。 Object
removeFirst() 移除并返回列表中的第一个元素。 Object
removeLast() 移除并返回列表中的最后一个元素。 Object

5.List的实现类之三:Vector

  • Vector 是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。

  • 在各种List中,最好把ArrayList作为默认选择。当插入、删除频繁时,使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。

  • 特有方法:

方法名称 方法描述
addElement(Object obj) 将指定的元素添加到此向量的末尾。
insertElementAt(Object obj, int index) 在指定的索引处插入指定的元素。原来在该位置和所有后续元素上的元素都向右移动。
setElementAt(Object obj, int index) 将指定索引处的元素设置为指定的对象。
removeElement(Object obj) 从向量中移除指定的元素。如果存在多个匹配的元素,则只移除第一个匹配的元素。
removeAllElements() 从向量中移除所有元素。

五、Collection子接口2:Set

1.Set接口概述

  • Set接口是Collection的子接口,Set接口相较于Collection接口没有提供额外的方法

  • Set 集合不允许包含相同的Value,如果试把两个相同的Value加入同一个 Set 集合中,则添加操作失败。因为Set集合是基于哈希表的一种数据结构,在插入元素时会根据元素的哈希值进行判断和处理,确保集合中没有重复的元素。

  • Set集合支持的遍历方式和Collection集合一样:foreach和Iterator。

  • Set的常用实现类有:HashSet、TreeSet、LinkedHashSet。

2.Set主要实现类:HashSet

详解(如果你想了解更多,可跳转到另一篇文章查看)

HashSet概述:

  1. 无序性:HashSet中的元素是无序的,不会按照插入的顺序进行存储和访问。

  2. 不可重复性:HashSet中的元素是唯一的,不会存在重复的元素。这是通过哈希表的机制来实现的。

  3. 允许存储null值:HashSet允许存储一个null元素。

  4. 内部实现机制:HashSet基于哈希表实现,使用了哈希函数来计算元素的存储位置,所以HashSet集合中元素的无序性,不等同于随机性。这里的无序性与元素的添加位置有关。具体来说:我们在添加每一个元素到数组中时,具体的存储位置是由元素的hashCode()调用后返回的hash值决定的。导致在数组中每个元素不是依次紧密存放的,表现出一定的无序性。

  5. HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法得到的哈希值相等,并且两个对象的 equals()方法返回值为true。

  6. 对于存放在Set容器中的对象,对应的类一定要重写hashCode()和equals(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。

  7. HashSet集合中元素的无序性,不等同于随机性。这里的无序性与元素的添加位置有关。具体来说:我们在添加每一个元素到数组中时,具体的存储位置是由元素的hashCode()调用后返回的hash值决定的。导致在数组中每个元素不是依次紧密存放的,表现出一定的无序性。

 HashSet方法:HashSet (Java SE 11 & JDK 11 ) (runoob.com)

 方法:

方法 描述
boolean add​(E e) 如果指定的元素尚不存在,则将其添加到此集合中。
void clear() 从该集中删除所有元素。
boolean contains​(Object o) 如果此 set 包含指定的元素,则返回 true。
boolean isEmpty() 如果此集合不包含任何元素,则返回 true。
Iterator<E> iterator() 返回此 set 中元素的迭代器。
boolean remove​(Object o) 如果存在,则从该集合中移除指定的元素。
int size() 返回此集合中的元素数(基数)。

示例:

去除重复数字值:

public static List duplicateList(List a) {
        HashSet set = new HashSet();
        set.addAll(a);
        return new ArrayList(set);
    }
    public static void main(String[] args) {
        Integer[] array = {1, 1, 3, 4, 4};
        // 将数组转换为集合
        List list = Arrays.asList(array);
        //list转为set达到去重的效果
        List list2 = duplicateList(list);
        for (Object integer : list2) {
            System.out.println(integer);
        }
    }

3.Set主要实现类二:LinkedHashSet

LinkedHashSet是Java集合框架中的一种集合实现,它继承自HashSet类,它根据元素的 hashCode 值来决定元素的存储位置,同时使用一个双向链表维护元素的插入顺序

与HashSet相比,LinkedHashSet有以下特点:

  1. 保持插入顺序:LinkedHashSet保持了元素的插入顺序。当我们向LinkedHashSet中添加元素时,它们会按照添加的顺序被保存,并且在遍历时按照相同的顺序返回。这使得LinkedHashSet非常适合于需要按照元素的插入顺序进行遍历或组织的场景。

  2. 高效的查找操作:与HashSet一样,LinkedHashSet使用哈希表实现元素的存储,因此查找元素的效率很高。在大多数查找操作中,LinkedHashSet的性能与HashSet相当。

  3. 相对较高的存储开销:由于LinkedHashSet需要维护元素插入顺序,它需要额外的存储空间来维护链表。因此,相对于HashSet,LinkedHashSet在存储方面稍微占用更多的内存。 

public class Test {
    public static void main(String[] args) {
        LinkedHashSet set = new LinkedHashSet<>();

        // 添加元素
        set.add("apple");
        set.add(1);
        set.add(2);
        set.add('e');
        set.add(0.14159);

        // 遍历集合
        for (Object element : set) {
            System.out.println(element);
        }

        // 判断元素是否存在
        boolean contains = set.contains(2 );
        System.out.println("Contains '2': " + contains);

        // 移除元素
        boolean removed = set.remove(1);
        System.out.println("Removed '1': " + removed);
        //按添加时的顺序输出
        System.out.println(set);
    }
}

输出:

apple
1
2
e
0.14159
Contains '2': true
Removed '1': true
[apple, 2, e, 0.14159]

 4.Set实现类之三:TreeSet

1.TreeSet概述

  • TreeSet 是 SortedSet 接口的实现类,TreeSet 可以按照添加的元素的指定的属性的大小顺序进行遍历。

  • TreeSet底层使用红黑树结构存储数据

  • TreeSet特点:不允许重复、实现排序(自然排序或定制排序)

  • TreeSet 两种排序方法自然排序定制排序。默认情况下,TreeSet 采用自然排序。

    • 自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。

      • 如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。

      • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。

    • 定制排序:如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法。

      • 利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。

      • 要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。

  • 因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象

 常用方法:

方法 描述
add(E e) 向TreeSet中添加指定的元素。
addAll(Collection c) 将指定集合中的所有元素添加到TreeSet中。
clear() 从TreeSet中移除所有元素。
contains(Object o) 检查TreeSet中是否包含指定的元素。
first() 返回TreeSet中的第一个(最小)元素。
last() 返回TreeSet中的最后一个(最大)元素。
isEmpty() 检查TreeSet是否为空。
remove(Object o) 从TreeSet中移除指定的元素。
size() 返回TreeSet中的元素数量。
iterator() 返回在TreeSet中元素上进行迭代的迭代器。
subSet(E fromElement, E toElement) 返回一个子集,包括从fromElement(包括)到toElement(不包括)的所有元素。
headSet(E toElement) 返回一个子集,包括小于toElement的所有元素。
tailSet(E fromElement) 返回一个子集,包括大于等于fromElement的所有元素。
ceiling(E e) 返回TreeSet中大于或等于给定元素e的最小元素。
floor(E e) 返回TreeSet中小于或等于给定元素e的最大元素。

示例:创建了一个自定义的比较器AgeComparator,它比较Student对象的年龄属性。然后将该比较器传递给TreeSet的构造函数,使得集合按照学生的年龄进行排序。

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetObjectPropertyOrderingExample {
    public static void main(String[] args) {
        TreeSet set = new TreeSet<>(new AgeComparator());

        // 添加学生对象
        set.add(new Student("Alice", 20));
        set.add(new Student("Bob", 18));
        set.add(new Student("Charlie", 22));

        // 遍历集合(按照年龄排序)
        for (Student student : set) {
            System.out.println(student.getName() + " : " + student.getAge());
        }
    }
}

class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

class AgeComparator implements Comparator {
    @Override
    public int compare(Student s1, Student s2) {
        return Integer.compare(s1.getAge(), s2.getAge());
    }
}

 其中:

(new LengthComparator()) 是创建一个比较器的实例,并将其作为参数传递给构造函数的简写方式,允许在创建TreeSet时即刻创建并传递一个比较器。

如果你更容易理解完整的步骤,可以按照下面的方式进行:

  1. 首先,你需要创建一个实现了Comparator接口的类,该接口指定了比较器的行为。
class LengthComparator implements Comparator {
    @Override
    public int compare(String s1, String s2) {
        return Integer.compare(s1.length(), s2.length());
        //如果s1.length()小于s2.length(),则返回负整数值。
        //如果s1.length()等于s2.length(),则返回0。
        //如果s1.length()大于s2.length(),则返回正整数值。
    }
}
  1. 接下来,你可以实例化比较器的对象:
Comparator lengthComparator = new LengthComparator();
  1. 然后,你可以使用该比较器对象创建TreeSet对象,并传递比较器对象作为参数:
TreeSet set = new TreeSet<>(lengthComparator);

综合以上三步,你可以用下面的代码来替代 (new LengthComparator()) 这样的写法:

Comparator lengthComparator = new LengthComparator();
TreeSet set = new TreeSet<>(lengthComparator);

这样更详细的写法可能更容易理解,但是对于简单的比较器,可以直接在构造函数中使用new 比较器类名()的方式来创建并传递比较器对象。

输出:

Bob : 18

Alice : 20

Charlie : 22

六、总结

List接口的实现类特点:

  1. ArrayList:基于数组实现,支持随机访问和快速的插入/删除操作。适用于频繁访问元素和对元素进行插入和删除的场景,但不适用于频繁的插入和删除操作。
  2. LinkedList:基于链表实现,支持高效的插入/删除操作和快速的查找操作。适用于频繁插入和删除元素的场景,但访问元素性能相对较低。LinkedList还实现了Deque接口,它提供了一系列特殊的链表操作,例如添加/删除首尾元素、获取首尾元素等。
  3. Vector:与ArrayList类似,但是是线程安全的(采用同步机制)。

ArrayListLinkedList是不安全的,这意味着它们在多线程环境下不能保证线程安全。如果多个线程同时修改一个ArrayListLinkedList实例,可能会导致数据不一致或出现并发访问异常。因此,在多线程环境下使用时,需要使用额外的同步机制来保证线程安全,例如使用Collections.synchronizedList等方法或使用并发集合类CopyOnWriteArrayList等。

Vector是线程安全的,它对其方法进行了同步化,以保证多线程环境下的安全访问。这意味着多个线程可以安全地同时修改一个Vector实例,而不会导致数据不一致或出现并发访问异常。然而,这种同步化会带来额外的开销,可能导致在性能上略有劣势。

在Java 1.2版本之后,引入了更高效的并发集合类,如ConcurrentHashMapConcurrentLinkedDequeCopyOnWriteArrayList,它们提供了更好的线程安全性和性能。因此,在现代的Java应用程序中,通常建议使用这些并发集合类来替代VectorArrayListLinkedList

Set接口的实现类特点:

  1. 它们在多线程环境下都不能保证线程安全
  2. HashSet:基于哈希表实现,不保证元素的顺序,并且不可重复。查找元素速度快,但无法保持元素的顺序。
  3. LinkedHashSet:基于链表和哈希表实现,使用一个双向链表维护元素的插入顺序。相比HashSet,插入和删除操作稍慢一些,但仍然较快。
  4. TreeSet:基于红黑树实现,能够保持元素的有序性。插入和删除操作的性能较慢,但查找元素和按序访问元素的性能非常高。

List接口提供了有序的、可重复的集合,适用于需要保持元素插入顺序或允许重复元素的场景。Set接口提供了无序的、不可重复的集合,适用于需要确保元素唯一性和不关心元素顺序的场景。

需要根据实际需求选择合适的List和Set实现类。如果需要频繁插入和删除元素,可以选择LinkedList和HashSet。如果需要高效的随机访问和根据元素顺序迭代,可以选择ArrayList和LinkedHashSet。如果需要有序集合,可以选择TreeSet或LinkedHashSet。

方法总结:

List接口方法

功能 方法 描述
插入元素 void add(int index, Object ele) 在index位置插入ele元素
boolean addAll(int index, Collection eles) 从index位置开始将eles中的所有元素添加进来
获取元素 Object get(int index) 获取指定index位置的元素
List subList(int fromIndex, int toIndex) 返回从fromIndex到toIndex位置的子集合
获取元素索引 int indexOf(Object obj) 返回obj在集合中首次出现的位置
int lastIndexOf(Object obj) 返回obj在当前集合中末次出现的位置
删除和替换元素 Object remove(int index) 移除指定index位置的元素,并返回此元素
Object set(int index, Object ele) 设置指定index位置的元素为ele

LinkedList实现类方法:

 Vector实现类方法:

 HashSet实现类方法:

方法 描述
boolean add​(E e) 如果指定的元素尚不存在,则将其添加到此集合中。
void clear() 从该集中删除所有元素。
boolean contains​(Object o) 如果此 set 包含指定的元素,则返回 true。
boolean isEmpty() 如果此集合不包含任何元素,则返回 true。
Iterator<E> iterator() 返回此 set 中元素的迭代器。
boolean remove​(Object o) 如果存在,则从该集合中移除指定的元素。
int size() 返回此集合中的元素数(基数)。

 Tree实现类方法

方法 描述
add(E e) 向TreeSet中添加指定的元素。
addAll(Collection c) 将指定集合中的所有元素添加到TreeSet中。
clear() 从TreeSet中移除所有元素。
contains(Object o) 检查TreeSet中是否包含指定的元素。
first() 返回TreeSet中的第一个(最小)元素。
last() 返回TreeSet中的最后一个(最大)元素。
isEmpty() 检查TreeSet是否为空。
remove(Object o) 从TreeSet中移除指定的元素。
size() 返回TreeSet中的元素数量。
iterator() 返回在TreeSet中元素上进行迭代的迭代器。
subSet(E fromElement, E toElement) 返回一个子集,包括从fromElement(包括)到toElement(不包括)的所有元素。
headSet(E toElement) 返回一个子集,包括小于toElement的所有元素。
tailSet(E fromElement) 返回一个子集,包括大于等于fromElement的所有元素。
ceiling(E e) 返回TreeSet中大于或等于给定元素e的最小元素。
floor(E e) 返回TreeSet中小于或等于给定元素e的最大元素。

你可能感兴趣的:(JAVA,java,开发语言)