Java集合之Set集合

本文深入探讨Java中Set集合的不同实现,包括HashSet与TreeSet的特点及使用场景。详细介绍了HashSet的内部实现原理及其如何通过重写hashCode和equals方法实现自定义排序,同时讲解TreeSet的排序机制,提供基于compareTo方法的排序示例。

Java集合之Set集合



一、常见的Set集合

  • 首先Set,是个接口,其存储的元素,是不允许重复的。
  • 一旦有重复的元素出现,则后存储元素会将之前存储的元素进行覆盖.
  • 并且Set集合存储的数据是无序的。

1.HashSet

此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。

  • 它不保证 set 的迭代顺序,特别是它不保证该顺序恒久不变。
  • 此类允许使用 null 元素
常用的方法:

增:
1.add(E e):向集合中添加数据
2.addAll(Collection<? extends E> c):向集合中添加另一个集合中的数据

查:

3.contains(Object o):判断集合中是否存在某一个元素
4.containsAll(Collection<?> c) :判断集合中是否存在里一个集合中的元素
5.isEmpty():判断集合中是否存在元素,如果有元素存在则返回false否则返回true

6.size():返回集合中元素的个数
7.toArray():将集合变为Object数组
8.toArray(T[] a):将集合变为指定的泛型类型的数组

删:

9.remove(Object o):从集合中删除指定的元素
10.removeAll(Collection<?> c) :从集合中删除指定集合中的全部的元素

注意:Set接口下集合的无序,实际上是按照哈希码值的的顺序存储,而其不可重复的规则也是按照equals方法里的规则,我们如果想要手动改变顺序和重复规则也是可以的。只需要在当前类重写这两个方法 hashCode()equals()。

HashSet的排序

hashCode()重写:(这里我是传的Person类对象,里面有name ,age属性)

public int hashCode() {
		// TODO Auto-generated method stub
		return 对象名.getName().hashCode() * Person类对象名.getAge();
		/*
		hashCode()是int类型,会返回一个哈希码值,所以我们可以返回一个自定义的码值,
	比如HashSet中我们存Person对象,按照年龄大小和字符串在字典里的顺序一同排序,
	我们可以return Person类对象名.getName().hashCode() * Person类对象名.getAge();
		*/
	}

equals()重写:(这里我是传的也是Person类对象,里面有name ,age属性)

public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		if (this == obj) {//内存地址一样则为通同一对象
			return true;
		}

		if (!(obj instanceof Person)) {//如果传进来的不是Person类型直接匹配失败
			return false;
		}
		Person per = new Person();
		if (this.getName().equals(per.getName()) && this.getAge() == per.getAge()) {//属性值一直也判断为同一对象
 //getName()传过来的一般是String类型,String里面自带了hashCode()方法,所以直接能获得哈希码值,用它和年龄的乘积作为新的哈希码值返回,JVM就会用这个哈希码值去排序
			return true;
		} else {
			return false;
		}
	}

2.TreeSet

  • 可以排序的set集合的实现
  • 在使用TreeSet存储数据的时候,存储的数据类型,必须是java.lang.Comparable接口的子类。因为TreeSet在进行排序的时候,需要使用到java.lang.Comparable中给我们提供的compareTo方法。
    Comparable:内比较器
TreeSet的排序
  • 利用Comparable接口内比较器
  • 利用Comparator外比较器

TreeSet的排序规则,**只看其compareTo方法**,我们也可以自己决定,我们只需要在实现Comparable接口的类重写compareTo方法即可

compareTo方法的重写:

	public int compareTo(Person o) {
		if (this.getAge() < o.getAge()) {
			return -1;//将当前对象和传入的参数对象比较,比参数小则往前排,返回负数
		} else if (this.getAge() > o.getAge()) {
			return 1;//将当前对象和传入的参数对象比较,比参数大则往后排,返回正数
		} else {
			return this.getName().compareTo(o.getName());//当前对象的name时字符串类型,直接用其compaerTo和参数名字比较,将其返回值返回
		}
	}

Comparator:外比较器

使用时,写一个第三方的类,继承此接口,指定传入的泛型,重写compare方法和equals方法即可

提供的方法:

1.int compare(T o1,T o2):比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数

2.boolean equals(Object obj):指示某个其他对象是否“等于”此 Comparator

总结:

TreeSet的操作方式与HashSet一样,在方法上没有区别。
只是判断是否重复的方式有区别:
HashSet是根据equals方法和hashcode方法来判断是否重复
TreeSet是根据compareTo()方法区分是否重复并进行排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值