【Set】Set集合有序与无序测试案例:HashSet,TreeSet,LinkedHashSet(122)

34 篇文章 1 订阅

常见的Set集合:HashSet,TreeSet,LinkedHashSet

三者间的联系
(1)HashSet、TreeSet是Set的两个典型实现,LinkedHashSet是HashSet的实现类。简单来说,HashSet的性能总是比TreeSet好(特别是最常用的添加、查询元素等操作),因为TreeSet需要额外的红黑树算法来维护集合元素的次序。只有当需要一个排序的Set时,才应该使用TreeSet,否则都应该使用HashSet。
(2)对于LinkedHashSet,对于普通的插入、删除操作,LinkedHashSet比HashSet要略微慢一点,这是因为维护链表所带来的额外的开销造成的,但由于有了链表,遍历LinkedHashSet会更快。
(3)还有一点需要指出的是:Set的三个实现类(HashSet、TreeSet和EnumSet)都是线程不安全的,如果有多个线程同时访问一个Set集合,并且有超过一个线程修改了该Set集合,则必须手动保证Set集合的同步性。通常可以通过Collections工具类的sysnchronizedSortedSet方法来“包装”该Set集合。所以,最好在创建的时候进行,以防止对Set集合的意外非同步访问。

三者间的区别

1 .HashSet

HashSet是基于HashMap来实现的,操作很简单,更像是对HashMap做了一次“封装”,而且只使用了HashMap的key来实现各种特性。
HashSet是通过HashMap实现,整个HashSet的核心就是HashMap。HashMap中的键作为HashSet中的值,HashMap中的值通过创建一个假的value来实现。

不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
HashSet不是同步的。如果多个线程同时访问一个HashSet,假设有两个或者两个以上线程同时修改了HashSet集合时,则必须通过代码来保证同步。
集合元素值可以是null。
HashSet类判断两个元素是否相等,需要两个条件,第一个条件:equals()的结果为true,第二个条件:hashCode()的值相等,即对应的元素的hashCode码要相同。

HashSet集合的优点:
它可以通过一个对象快速查找到集合中的对象。hash算法的价值在于查找速度很快:它是通过将对象转变为对应的hashCode值,然后按照hashCode值在桶中对应位置取出该元素。

2 .TreeSet

该类实现的接口:Serializable, Cloneable, Iterable, Collection, NavigableSet, Set, SortedSet
TreeSet原理:

TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。
TreeSet并不是根据元素的插入顺序进行排序的,而是根据元素的实际值大小来进行排序。
与HashSet集合采用的hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构来存储集合元素。其中,TreeSet支持两种排序方法:自然排序和定制排序,在默认情况下,TreeSet采用自然排序。
使用该集合的类必须实现Comparable接口中的compare To()方法,因为该类是有序的。

3 .LinkedHashSet
该类实现的接口:Serializable, Cloneable, Iterable, Collection, Set
LinkedHashSet原理:

LinkedHashSet是HashSet接口的实现类,LinkedHashSet集合也是根据元素的hashCode值来决定元素的存储位置,但他同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。也就是说,当遍历LinkedHashSet集合里的元素时,LinkedHashSet将会按照元素的添加顺序来访问集合里的元素。
LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能,但在迭代访问Set里的全部元素时将会有很好的性能,因为它以链表来维护内部的顺序。
虽然LinkedHashSet使用了链表记录集合元素的添加顺序,但LinkedHashSet依然是HashSet,因此它仍然是不允许集合元素重复。

测试案例

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class day16 {
	public static void main(String[] args) {
		
		
		Set<String> hashSet = new HashSet<>();
		Set<String> treeSet = new TreeSet<>();
		Set<String> linkedHashSet = new LinkedHashSet<>();
		
		Set<Integer> hashSet2 = new HashSet<>();
		Set<Integer> treeSet2 = new TreeSet<>();
		Set<Integer> linkedHashSet2 = new LinkedHashSet<>();
		
		Set<String> hashSet3 = new HashSet<>();
		Set<String> treeSet3 = new TreeSet<>();
		Set<String> linkedHashSet3 = new LinkedHashSet<>();
				
		List<String> list1 = Arrays.asList("黄","河","之","水","天","上","来","奔","流","到","海","不","复","回",
				"黄","河","之","水","天","上","来","奔","流","到","海","不","复","回");
		List<Integer> list2 = Arrays.asList(2  , 1  , 4 , 3  ,  6 , 5  ,7  ,  14, 13  ,12  , 11 ,10 , 9 , 8,
				2  , 1  , 4 , 3  ,  6 , 5  ,7  ,  8 , 9  ,10  , 11 ,12 , 13 , 14);
		List<String> list3 = Arrays.asList("2"  , "1"  , "4" , "3"  ,  "6" , "5"  ,"7"  ,  "14", "13"  ,"12"  , "11" ,"10" , "9" , "8",
				"2"  , "1"  , "4" , "3"  ,  "6" , "5"  ,"7"  ,  "8" , "9"  ,"10"  , "11" ,"12" , "13" , "14");
		hashSet.addAll(list1);
		System.out.println("hashSet1:"+hashSet);
		hashSet2.addAll(list2);
		System.out.println("hashSet2:"+hashSet2);
		hashSet3.addAll(list3);
		System.out.println("hashSet3:"+hashSet3);
		System.out.println("------------------------------------------------");
		
		treeSet.addAll(list1);
		System.out.println("treeSet1:"+treeSet);
		treeSet2.addAll(list2);
		System.out.println("treeSet2:"+treeSet2);
		treeSet3.addAll(list3);
		System.out.println("treeSet3:"+treeSet3);
		System.out.println("------------------------------------------------");
		
		linkedHashSet.addAll(list1);
		System.out.println("linkedHashSet1:"+linkedHashSet);
		linkedHashSet2.addAll(list2);
		System.out.println("linkedHashSet2:"+linkedHashSet2);
		linkedHashSet3.addAll(list3);
		System.out.println("linkedHashSet3:"+linkedHashSet3);
		System.out.println("-------------------------------------------------");
		
	}
}

测试输出

hashSet1:[,,,,,,,,,,,,,]
hashSet2:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
hashSet3:[11, 12, 13, 14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
--------------------------------------------------------
treeSet1:[,,,,,,,,,,,,,]
treeSet2:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
treeSet3:[1, 10, 11, 12, 13, 14, 2, 3, 4, 5, 6, 7, 8, 9]
--------------------------------------------------------
linkedHashSet1:[,,,,,,,,,,,,,]
linkedHashSet2:[2, 1, 4, 3, 6, 5, 7, 14, 13, 12, 11, 10, 9, 8]
linkedHashSet3:[2, 1, 4, 3, 6, 5, 7, 14, 13, 12, 11, 10, 9, 8]
--------------------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KevinDuc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值