Java集合框架--Set(HashSet,TreeSet,LinkedHashSet)

S‌et概述

Set是Java集合框架中的一部分,‌代表了一个不重复元素的集合,‌每个元素在集合中都是唯一的‌。‌Set集合的特点是无序性,‌即集合内的元素不按任何特定顺序排列,‌且每个元素都是唯一的。‌Set集合的主要实现类有HashSet、‌TreeSet和LinkedHashSet。‌

  • HashSet基于哈希表实现,‌具有良好的插入、‌删除和查找性能,‌但不保证元素的迭代顺序。‌
  • TreeSet基于红黑树实现,‌元素自动排序,‌确保了集合内元素的排序顺序。‌
  • LinkedHashSet结合了HashSet和LinkedList的特性,‌它维护元素插入的顺序,‌同时仍然保证元素的唯一性‌。‌

HashSet

关于HashSet的使用,‌它是一个非常实用的集合类,‌在Java中广泛用于存储不重复的元素。‌以下是一些HashSet使用的基本要点:‌

1. 创建HashSet实例

你可以直接通过new HashSet<>()来创建一个HashSet实例,‌指定元素类型以享受编译时的类型检查。‌

HashSet hashSet = new HashSet<>();

2. 添加元素

使用方法add(E e)向HashSet中添加元素。‌如果HashSet中已存在该元素(‌通过hashCode()和equals()方法判断)‌,‌则添加操作不会成功,‌且返回false。‌

hashSet.add("Java");
hashSet.add("Python");

// 尝试添加重复元素

boolean result = hashSet.add("Java"); // 返回false,‌因为"Java"已经存在

3. 移除元素

使用方法remove(Object o)从HashSet中移除元素。‌如果HashSet包含指定的元素,‌则移除该元素并返回true。‌

hashSet.remove("Python"); // 移除"Python",‌如果成功则返回true

4. 遍历HashSet

你可以使用增强的for循环(‌也称为"for-each"循环)‌来遍历HashSet中的元素。‌

for (String item : hashSet) {
    System.out.println(item);
}

或者使用Java 8引入的forEach方法与Lambda表达式。‌

hashSet.forEach(item -> System.out.println(item));

5. 注意事项

  1. HashSet不保证集合的迭代顺序。‌如果你需要有序集合,‌可以考虑使用或。‌LinkedHashSetTreeSet
  2. HashSet是基于哈希表的实现,‌因此它提供了快速的查找、‌添加和删除操作。‌
  3. HashSet允许包含一个null元素。‌
  4. HashSet不是线程安全的。‌如果需要在多线程环境下使用,‌请考虑使用Collections.synchronizedSet或Java并发包中的并发集合java.util.concurrent。‌

6. 自定义对象

当在HashSet中存储自定义对象时,‌你需要确保该对象类重写了hashCode()和方法equals(),‌以确保HashSet能够正确地识别和处理重复对象。‌

HashSet总结

HashSet是Java集合框架中的一个重要部分,‌它实现了Set接口。‌HashSet基于哈希表(‌HashMap)‌实现,‌因此它不保证集合的迭代顺序。‌HashSet允许存储null元素,‌但最多只能有一个null元素,‌因为HashSet是通过元素的hashCode()和equals()方法来确保元素的唯一性的。‌

HashSet的主要特点包括:‌

  1. ‌不保证顺序‌:‌HashSet不保证集合中元素的顺序,‌特别是它不保证该顺序随时间保持不变。‌
  2. ‌唯一性‌:‌HashSet不允许有重复元素。‌当尝试添加一个已经存在于HashSet中的元素时,‌添加操作会失败(‌实际上,‌它不会改变HashSet,‌并返回false以指示添加未发生)‌。‌
  3. ‌基于哈希表‌:‌HashSet内部使用哈希表来存储元素,‌这提供了快速的查找、‌添加和删除操作。‌
  4. ‌null元素‌:‌HashSet可以包含一个null元素。‌
  5. ‌线程不安全‌:‌和大多数Java集合一样,‌HashSet不是线程安全的。‌如果多个线程同时访问一个HashSet实例,‌并且至少有一个线程从结构上修改了集合,‌那么它必须保持外部同步。‌
  6. ‌迭代器‌:‌HashSet提供了一个迭代器(‌Iterator)‌,‌允许你遍历集合中的元素。‌但是,‌需要注意的是,‌迭代器提供的是弱一致性的视图,‌这反映了某一时间点或者迭代开始时的集合状态。‌
  7. ‌性能‌:‌在大多数情况下,‌HashSet提供了比基于列表的集合(‌如ArrayList)‌更快的查找、‌添加和删除操作,‌特别是当集合变得非常大时。‌但是,‌由于它依赖于哈希码,‌因此元素的哈希码分布对性能有很大影响。‌
  8. 使用HashSet时,‌你应该注意元素的hashCode()和equals()方法的实现,‌以确保HashSet能够正确地识别和处理重复元素。‌如果两个对象通过equals()方法比较是相等的,‌那么它们的hashCode()方法必须返回相同的整数值。‌

TreeSet

TreeSet是Java集合框架中的一个重要类,‌它实现了SortedSet接口,‌因此其元素是自动排序的。‌以下是一些关于TreeSet的基本使用方法:‌

1.‌创建TreeSet‌

你可以创建一个空的TreeSet,‌或者通过传递一个Comparator来定制排序规则,‌或者传递一个SortedSet(‌或其子类如TreeSet)‌来创建一个具有相同元素和排序规则的TreeSet。‌

TreeSet treeSet = new TreeSet<>();

// 或者使用Comparator来定制排序规则

TreeSet treeSetWithComparator = new TreeSet<>(Comparator.reverseOrder());

2.‌添加元素‌

使用add()方法可以向TreeSet中添加元素。‌如果添加的元素已经存在,‌则添加操作不会成功,‌因为TreeSet中的元素是唯一的。‌

treeSet.add(1);
treeSet.add(2);
treeSet.add(3);
// 尝试添加重复元素,‌不会成功
treeSet.add(2);

3.‌删除元素‌

使用remove()方法可以删除TreeSet中的元素。‌如果元素存在,‌则删除成功,‌并返回true;‌如果元素不存在,‌则删除失败,‌并返回false。‌

treeSet.remove(2);

4.‌查找元素‌

使用contains()方法可以检查TreeSet中是否包含某个元素。‌

boolean contains = treeSet.contains(3);

5.‌遍历元素‌

你可以使用迭代器(‌Iterator)‌或者for-each循环来遍历TreeSet中的元素。‌由于TreeSet中的元素是自动排序的,‌所以遍历出来的元素也是按照排序规则排列的。‌

for-each:

for (Integer num : treeSet) {
    System.out.println(num);
}

迭代器:

import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetExample {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet<>();
        // 向TreeSet中添加一些元素
        treeSet.add(3);
        treeSet.add(1);
        treeSet.add(2);
        treeSet.add(5);
        treeSet.add(4);

        // 使用迭代器遍历TreeSet
        Iterator iterator = treeSet.iterator();
        while (iterator.hasNext()) {
            Integer element = iterator.next();
            System.out.println(element);
        }
    }
}

6.‌获取子集‌

TreeSet提供了headSet()、‌subSet()tailSet()方法来获取TreeSet的子集。‌这些方法分别用于获取小于某个元素的子集、‌两个元素之间的子集和大于某个元素的子集。‌

SortedSet headSet = treeSet.headSet(2);
SortedSet subSet = treeSet.subSet(1, 3);
SortedSet tailSet = treeSet.tailSet(2);

7.‌比较器‌

当你需要自定义排序规则时,‌可以向TreeSet的构造函数中传递一个Comparator对象。‌这个Comparator对象必须实现compare()方法来定义元素之间的排序规则。‌

TreeSet treeSetWithCustomComparator = new TreeSet<>(new Comparator() {
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
});

以上是关于TreeSet的一些基本使用方法。‌由于TreeSet是基于红黑树实现的,‌所以它的插入、‌删除和查找操作的时间复杂度都是O(log n),‌这使得TreeSet在需要排序的集合中非常有用。‌

TreeSet总结

TreeSet是Java集合框架中的一个有序集合类,‌它实现了SortedSet接口,‌具有以下主要特点:‌

  1. ‌元素有序‌:‌TreeSet中的元素按照自然顺序或者通过自定义的比较器进行排序,‌保证了元素的有序性。‌
  2. ‌去重性‌:‌TreeSet中不允许存在重复的元素,‌当尝试添加重复元素时,‌新元素将被忽略。‌
  3. ‌基于红黑树‌:‌TreeSet内部使用红黑树数据结构来存储元素,‌红黑树是一种自平衡二叉查找树,‌可以保持较好的插入、‌删除和查找性能。‌
  4. TreeSet适用于需要存储有序且唯一的数据的场景,‌例如按照字母顺序存储单词列表、‌按照分数排序学生成绩等‌。‌

LinkedHashSet

在Java集合框架中,‌LinkedHashSet是一个非常有用的类,‌它结合了HashSet和LinkedList的特性。‌维护着一个运行于LinkedHashSet所有条目的双重链接列表,‌这个列表定义了迭代器的遍历顺序,‌即按照元素被添加到集合中的顺序(‌插入顺序)‌进行遍历。‌以下是关于如何正确使用LinkedHashSet的一些指导:‌

1. 创建实例LinkedHashSet

首先,‌你需要创建一个LinkedHashSet的实例,‌并指定存储元素的类型。‌

LinkedHashSet linkedHashSet = new LinkedHashSet<>();

2. 添加元素

使用add(E e)方法向LinkedHashSet中添加元素。‌由于LinkedHashSetSet的一个实现,‌因此它不允许重复元素。‌如果尝试添加已经存在的元素,‌则添加操作将不会改变集合,‌并且方法会返false。‌

linkedHashSet.add("Java");
linkedHashSet.add("Python");
linkedHashSet.add("C++");

// 尝试添加重复元素

boolean result = linkedHashSet.add("Java"); // 返回false,‌因为"Java"已经存在

3. 遍历LinkedHashSet

由于LinkedHashSet维护了元素的插入顺序,‌因此当你遍历它时,‌元素将按照它们被添加到LinkedHashSet集合中的顺序返回。‌你可以使用增强的for循环或迭代器来遍历。‌

增强的for循环 :

for (String item : linkedHashSet) {
    System.out.println(item);
}

迭代器‌:‌

Iterator iterator = linkedHashSet.iterator();
while (iterator.hasNext()) {
    String item = iterator.next();
    System.out.println(item);
}

4. 移除元素

使用remove(Object o)方法从LinkedHashSet中移除元素。‌如果集合包含指定的元素,‌则remove方法会返回true,‌并且该元素将从集合中移除。‌

linkedHashSet.remove("Python"); // 移除"Python"

5. 注意事项

  1. LinkedHashSet不是线程安全的。‌如果多个线程同时访问一个实例,‌并且至少有一个线程从结构上修改了LinkedHashSet集合,‌那么它必须保持外部同步。‌
  2. LinkedHashSet内部维护了一个双向链表来保持元素的插入顺序,‌这使得它在迭代时能够按照元素的添加顺序返回元素,‌但这也略微增加了其内存消耗和某些操作的复杂度。‌
  3. LinkedHashSet与HashSet一样,‌也依赖于元素的hashCode()和equals()方法来确定元素的唯一性。‌因此,‌在将元素添加到LinkedHashSet之前,‌请确保这些方法的实现是正确的。‌

LinkedHashSet小结

‌LinkedHashSet是Java集合框架中的一个类,‌它继承自HashSet并实现了Set接口,‌具有可预知的迭代顺序和元素的唯一性‌。‌以下是关于LinkedHashSet的详细解释:‌

‌特性‌:‌

  1. ‌有序性‌:‌维护了一个双向链表,‌可以保持元素的插入顺序,‌即元素被添加到集合中的顺序就是它们在集合中的顺序。‌
  2. ‌唯一性‌:‌不允许存储重复的元素。‌
  3. ‌非线程安全‌:‌如果有多个线程同时访问并修改LinkedHashSet,‌需要外部同步来保证数据的一致性。‌

‌内部实现‌:‌

底层是一个哈希表(‌数组+链表/红黑树)‌+链表,‌多了一条链表记录元素存储的顺序,‌保证元素有序。‌

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