Set

Set集合类要求集合中不存在相同的元素。


一、HashSet

1、核心结构

private transient HashMap<E,Object> map; //内部采用HashMap实现,key为保存的元素的hash值,value为PRESENT.

private static final Object PRESENT = new Object(); //value值


public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{

	public HashSet() {
		map = new HashMap<>();
	}

	public HashSet(int initialCapacity) {
		map = new HashMap<>(initialCapacity);
	}

	public HashSet(int initialCapacity, float loadFactor) {
		map = new HashMap<>(initialCapacity, loadFactor);
	}

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

	public boolean add(E e) {
		return map.put(e, PRESENT)==null;
	}

	public boolean remove(Object o) {
		return map.remove(o)==PRESENT;
	}

	public int size() {
		return map.size();
	}

	public void clear() {
		map.clear();
	}

	public int size() {
		return map.size();
	}
}




二、LinkedHashSet

有序的HashSet集合,保存了元素的添加顺序.

public class LinkedHashSet<E>
    extends HashSet<E>  implements Set<E>, Cloneable, java.io.Serializable {
	
public LinkedHashSet(int initialCapacity, float loadFactor) {
	super(initialCapacity, loadFactor, true);//LinkedHashMap实现
}

public LinkedHashSet(int initialCapacity) {
	super(initialCapacity, .75f, true); //LinkedHashMap实现
}

public LinkedHashSet() {
	super(16, .75f, true); //LinkedHashMap实现
}
	
}	


三、TreeSet

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
 private static final Object PRESENT = new Object();
 
	public TreeSet() {
		this(new TreeMap<E,Object>());  //内部使用TreeMap实现
	}
	
	public TreeSet(Comparator<? super E> comparator) {
		this(new TreeMap<>(comparator));   //内部使用TreeMap实现

	}	

	public boolean add(E e) {
		return m.put(e, PRESENT)==null;
	}

}

TreeSet存储对象的时候, 可以排序, 但是需要指定排序的算法,默认采用自然顺序排序。


自然顺序排序

//自然顺序 
SortedSet<String> set3=new TreeSet<String>();
set3.add("D");
set3.add("B");
set3.add("D");
set3.add("C");
set3.add("A");
set3.add("C");
System.out.println(set3);//ABCD

set3=new TreeSet<String>();
set3.add("1");
set3.add("4");
set3.add("2");
set3.add("3");
System.out.println(set3);//1234

自定义类的对象排序

1、类实现Comparable接口

public class Person implements Comparable<Person>{
	private String name;
	private int age;
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Person per) {//应该将所有属性都进行比较
		 if(this.age>per.age){
			 return 1;
		 }
		 if(this.age<per.age){
			 
			return -1;
		 }else{
			 return this.name.compareTo(per.name);//调用String中的compareTo()方法
		 }
		
	}
}	


2、自定义Comparator,通过TreeSet的构造函数传入  

 

TreeSet<Person> treeSet = new TreeSet<Person>(comparator);
Comparator comparator = new Comparator<Person>() {


@Override
public int compare(Person o1, Person o2) {
    if (o1.age > o2.age) {
         return 1;
    } else if (o1.age < o2.age) {
         return -1;
    }
    return o1.name.compareTo(o2.name);//调用String中的compareTo()方法
};

在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较, 根据比较结果使用二叉树形式进行存储。


四、Set保存类对象

如果是类对象,需要重写该类的hashCode()和equals()方法,这样Set集合才能正常去重

public class Person {  
	private String name;
	private int age;
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	
	@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;
		Person2 other = (Person2) 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;
	}

//测试
Set<Person> set=new HashSet<Person>();
set.add(new Person("张三", 21));
set.add(new Person("李四", 22));
set.add(new Person("王五", 23));
set.add(new Person("王五", 23)); //重复
set.add(new Person("赵六", 24));
set.add(new Person("赵六二", 24));	
}
		









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值