欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

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

发布时间:2024/4/11 43 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Java集合框架:Set(HashSet,LinkedHashSet,TreeSet) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


欢迎跳转到本文的原文链接:https://honeypps.com/java/java-collection-set/

Set概述

 Set几乎都是内部用一个Map来实现, 因为Map里的KeySet就是一个Set,而value是假值,全部使用同一个Object。Set的特征也继承了那些内部Map实现的特征。


HashSet

1. 定义

package java.util; public class HashSet<E>extends AbstractSet<E>implements Set<E>, Cloneable, java.io.Serializable {private transient HashMap<E,Object> map;private static final Object PRESENT = new Object();public HashSet() {map = new HashMap<>();} //其余省略 }

2. 概述

 HashSet是基于HashMap来实现的,操作很简单,更像是对HashMap做了一次“封装”,而且只使用了HashMap的key来实现各种特性,而HashMap的value始终都是PRESENT。
HashSet不允许重复(HashMap的key不允许重复,如果出现重复就覆盖),允许null值,非线程安全
 罗列几个主要方法:

public Iterator<E> iterator() {return map.keySet().iterator();}public int size() {return map.size();}public boolean isEmpty() {return map.isEmpty();}public boolean contains(Object o) {return map.containsKey(o);}public boolean add(E e) {return map.put(e, PRESENT)==null;}public boolean remove(Object o) {return map.remove(o)==PRESENT;}public void clear() {map.clear();}

3. 使用

 案例1:

Set<String> set = new HashSet<>();set.add("s2");set.add("s3");set.add("s4");set.add("s2");set.add("s5");set.add("s1");set.add(null);set.add("s21");set.add("sw2");set.add("s2");for(String i:set)System.out.println(i);System.out.println(set);

 输出:

null s2 s1 sw2 s21 s5 s3 s4 [null, s2, s1, sw2, s21, s5, s3, s4]

LinkedHashSet

1. 定义(整个LinkedHashSet的代码)

package java.util; public class LinkedHashSet<E>extends HashSet<E>implements Set<E>, Cloneable, java.io.Serializable {private static final long serialVersionUID = -2851667679971038690L;public LinkedHashSet(int initialCapacity, float loadFactor) {super(initialCapacity, loadFactor, true);}public LinkedHashSet(int initialCapacity) {super(initialCapacity, .75f, true);}public LinkedHashSet() {super(16, .75f, true);}public LinkedHashSet(Collection<? extends E> c) {super(Math.max(2*c.size(), 11), .75f, true);addAll(c);} }

2. 概述

 HashSet有4个共有的构造函数:

public HashSet() {map = new HashMap<>();}public HashSet(Collection<? extends E> c) {map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));addAll(c);}public HashSet(int initialCapacity, float loadFactor) {map = new HashMap<>(initialCapacity, loadFactor);}public HashSet(int initialCapacity) {map = new HashMap<>(initialCapacity);}

 还有一个包级私有的构造函数:

HashSet(int initialCapacity, float loadFactor, boolean dummy) {map = new LinkedHashMap<>(initialCapacity, loadFactor);}

 这个构造函数就是LinkedHashSet的关键,整个LinkedHashSet的四个构造函数全部都是调用了HashSet中的这个包级私有的构造函数(构造函数中的dummy就是标记,无实用,为了实现方法的重载而已),也就是说LinkedHashSet就是基于LinkedHashMap实现的

3. 使用

案例2:

Set<String> set = new LinkedHashSet<>();set.add("s2");set.add("s3");set.add("s4");set.add("s2");set.add("s5");set.add("s1");set.add(null);set.add("s21");set.add("sw2");set.add("s2");for(String i:set)System.out.println(i);System.out.println(set);

 输出:

s2 s3 s4 s5 s1 null s21 sw2 [s2, s3, s4, s5, s1, null, s21, sw2]

允许null值,保留插入顺序,非线程安全。


TreeSet

1. 定义

package java.util; public class TreeSet<E> extends AbstractSet<E>implements NavigableSet<E>, Cloneable, java.io.Serializable {private transient NavigableMap<E,Object> m;private static final Object PRESENT = new Object();public TreeSet() {this(new TreeMap<E,Object>());}public TreeSet(Comparator<? super E> comparator) {this(new TreeMap<>(comparator));}public TreeSet(Collection<? extends E> c) {this();addAll(c);}public TreeSet(SortedSet<E> s) {this(s.comparator());addAll(s);} //其余省略 }

2. 概述

 TreeSet的内部基于TreeMap实现,同样value永远为PRESENT.
 案例3:

Set<String> set = new TreeSet<String>();set.add("s2");set.add("s3");set.add("s4");set.add("s2");set.add("s5");set.add("s1"); // set.add(null);set.add("s21");set.add("sw2");set.add("s2");for(String i:set)System.out.println(i);System.out.println(set);

 运行结果:

s1 s2 s21 s3 s4 s5 sw2 [s1, s2, s21, s3, s4, s5, sw2]

不允许重复,不允许null值(如果有基于null的比较器,就可以允许为null),默认按升序排列。
案例4(其中的Person2详细见《Comparable与Comparator浅析》):

Set<Person2> set = new TreeSet<Person2>(new Comparator<Person2>(){@Overridepublic int compare(Person2 o1, Person2 o2){if(o1==null || o2==null)return 0;return o1.getAge()-o2.getAge();}});Person2 p1 = new Person2("zzh",18);Person2 p2 = new Person2("jj",17);Person2 p3 = new Person2("qq",19);Person2 p4 = new Person2(null,19);set.add(p1);set.add(p2);set.add(p3);set.add(p4);System.out.println(set);

 输出结果:[jj:17, zzh:18, qq:19]
 可以看到不是强制性要求TreeSet的键为null。


参考资料:

  • 《Comparable与Comparator浅析》
  • 欢迎跳转到本文的原文链接:https://honeypps.com/java/java-collection-set/

    欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


    总结

    以上是生活随笔为你收集整理的Java集合框架:Set(HashSet,LinkedHashSet,TreeSet)的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。