Java Set集合知多少?

Set集合在开发中也会经常用到,有用的没用的都整理了一下。今天你Set了么?
这里写图片描述

1.基本概念

Set:一个不包含重复元素的collection接口,元素无序、唯一。

2.主要实现类

(1)HashSet

HashSet:实现Set接口,由哈希表支持,它不保证set的迭代顺序,无序唯一,不是同步的。

/**
 * 用户类
 * @author magic
 *
 */
public class User {

	String name;
	int age;

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}

	//自动生成hashCode()和equalis()方法,保证元素唯一
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}
   
public class Test_Set {

	public static void main(String[] args) {

		// 子类对象实例化接口
		Set set = new HashSet();
		// 添加元素
		set.add("sermia");
		set.add("nike");
		set.add("vans");
		// 通过输出可以看出,set集合是散列排序
		System.out.println(set);// [nike, sermia, vans]
		
		// 删除单个元素
		set.remove("sermia");
		System.out.println(set);// [nike, vans]
		// 删全部元素
		set.removeAll(set);
		System.out.println(set);// []
		
		// 移除此set中的所有元素
		// set.clear();
		
		Set<User> set2 = new HashSet<User>();
		// 添加自定义对象
		set2.add(new User("一一", 11));
		set2.add(new User("二二", 22));
		set2.add(new User("三三", 33));
		set2.add(new User("三三", 33));
		// 自定义对象没有重写User类的 hashCode()和equals(Object obj)
		// 自定义都会被添加到集合
		System.out.println(set2);
		// [User [name=一一, age=11], User [name=三三, age=33], User [name=三三,age=33], User [name=二二, age=22]]

		// 自定义对象需要重写了User类的 hashCode()和equals(Object obj)
		// 保证元素的唯一
		System.out.println(set2);
		// [User [name=二二, age=22], User [name=三三, age=33], User [name=一一,age=11]]
	}

}  

注:HashSet底层数据结构是哈希表,哈希表底层依赖hashCode()和equals()方法。集合添加元素的时候先判断hashCode()是否相同,不相同元素添加到集合;相同则执行equals()方法,equals()返回false,元素添加集合,返回true元素不添加到集合。hashCode()和equals()共同保证了集合元素的唯一性。

(2)TreeSet

TreeSet:实现Set接口,使用元素的自然顺序对元素进行排序,或者根据创建set时提供的Comparator(比较器排序)进行排序,有序(按某种规则排序)唯一,不是同步的。有序(按某种规则排序)唯一,不是同步的

  构造方法:
  
  //构造一个新的空set,该set根据其元素的自然顺序进行排序 
  TreeSet() 
 // 构造一个包含指定collection元素的新TreeSet,它按照其元素的自然顺序进行排序
  TreeSet(Collection<? extends E> c) 
 // 构造一个新的空TreeSet,它根据指定比较器进行排序
  TreeSet(Comparator<? super E> comparator) 
 // 构造一个与指定有序set具有相同映射关系和相同排序的新TreeSet 
  TreeSet(SortedSet<E> s) 
        //自然排序
        Set set = new TreeSet();
		//添加元素
		set.add("sermia");
		set.add("nike");
		set.add("vans");
		set.add("anta");
		// 通过输出可以看出,set集合按照某种规则进行了排序(首写字母)
		System.out.println(set);// [anta, nike, sermia, vans]

		//比较器排序
		Set<User> set2 = new TreeSet<User>(new Comparator<User>() {

			public int compare(User o1, User o2) {
			    //排序规则
				//返回<0,则在元素左边,>0则在元素右边,=0不添加到集合
				return o1.age-o2.age;
			}
		});
        //添加自定义对象
		set2.add(new User("一一", 11));
		set2.add(new User("二二", 22));
		set2.add(new User("三三", 33));

		System.out.println(set2);
		//输出看出按照了age大小进行了排序
		// [User [name=一一, age=11], User [name=二二, age=22], User [name=三三,age=33]]

注:TreeSet底层数据结构是红黑树,通过自然排序、比较器排序对元素排序。自然排序需要元素类实现Comparable接口,重写compareTo方法,通过控制返回值指定排序规则,而某些常用Java类已经实现了该接口,例如String,Integer等set的输出就可以证明。比较器排序需要集合构造方法接收Comparator的实现类对象,重写compare方法,通过返回值指定排序规则,当返回值为0时,不添加到集合。

(3)LinkedHashSet

LinkedHashSet:具有可预知迭代顺序的Set接口的哈希表和链接列表实现,有序唯一,不是同步的。有序唯一,不是同步的。

        Set set = new LinkedHashSet();
		// 添加元素
		set.add("sermia");
		set.add("nike");
		set.add("vans");
		set.add("anta");
		// 通过输出可以看出,LinkedHashSet集合是顺序输出
		System.out.println(set);// [sermia, nike, vans, anta]

		Set<User> set2 = new LinkedHashSet<User>();
		set2.add(new User("一一", 11));
		set2.add(new User("二二", 22));
		set2.add(new User("三三", 33));
        //输出顺序和添加顺序一致
		System.out.println(set2);
		// [User [name=一一, age=11], User [name=二二, age=22], User [name=三三,age=33]]

注:底层数据结构是链表和哈希表,链表保证元素有序,哈希表保证元素唯一。

注:更多方法查看API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值