Java容器学习之Set

Java的对象容器Collection


Collection的子接口有Set(元素不可重复),List(元素可重复有索引),Queue(队列).

二.Set

set关注唯一性也就是元素不可重复,以equals(),hashcode()来判断。分为HashSet,LinkedHashSet,TreeSet

1.HashSet无序且不可排序,使用对象的hashcode插入

2.LinkedHashSet,有序的HashSet,通过双向链接来维持对象之间的关系,顺序是元素的插入顺序。

3.TreeSet,可排序的Set(另外还有一个TreeMap),使用红黑树的结构,将元素按自然顺序做升序排列,可以实现Comparable或Comparator接口来自定义排序规则。

public class Employee implements Comparable{
	private String name;
	private int 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 Employee(){
		
	}
	public Employee(String name) {
		super();
		this.name = name;
	}
	public Employee(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 + ((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;
		Employee other = (Employee) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "Employee [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Object o) {
		Employee emp = (Employee)o;
		return this.name.compareTo(emp.name);
	}
}


public class SetTest {
	public static void main(String[] args) {
		//addItem();
		//addEmp();
		//addEmpToLinkedHashSet();
		addEmpToTreeSet();
	}
	
	/**
	 * HashSet的重复判断是这样的:
	 * hashcode不同,对象一定不同
	 * hashcode相同,判断==(比地址)
	 * ==不同,再比较equals
	 * hashcode()&&(==||equals()),满足此条件(hashcode相同并且(==,equals其中一个相同))就表明2对象相同
	 */
	static void addItem(){
		Set<string> set = new HashSet<string>();
		set.add("wanghaijun");
		set.add("mayu");
		set.add("luxiangdong");
		System.out.println("Size of Set: "+set.size());
		set.add("wanghaijun");//Set中的元素不可重复,所以此句代码添加不进元素
		System.out.println("Size of Set: "+set.size());
		
		set.add(new String("liqiang"));
		set.add(new String("liqiang"));
		System.out.println("Size of Set: "+set.size());
	}
	
	/**
	 * 自定义类型作为HashSet的元素时,如果不以默认的比较规则(地址hashcode)
	 * 必须重写hashcode和equals方法,并且比较规则要一致
	 */
	static void addEmp(){
		Set<employee> set = new HashSet<employee>();
		// 这2个Employee对象的hashcode是地址码,所以不同,我们可以重写hash和equals方法
		set.add(new Employee("wanghaijun"));
		set.add(new Employee("wanghaijun"));
		System.out.println(set.size());
		
		//printSet(set);
	}
	
	static void addEmpToLinkedHashSet(){
		Set<employee> set = new LinkedHashSet<employee>();//按插入顺序排序
		set.add(new Employee("wanghaijun"));
		set.add(new Employee("liqiang"));
		set.add(new Employee("mayu"));
		printSet(set);
	}
	
	static void printSet(Set set){
		// 方式1
		Iterator iter = set.iterator();
		while(iter.hasNext()){
			System.out.println(iter.next());
		}
		
		// 方式2
		for(Object o: set){
			System.out.println(o);
		}
	}
	
	static void addEmpToTreeSet(){
		// 自定义TreeSet的插入顺序规则
		// 方式1:构造TreeSet的时候以Comparator对象做为构造参数
		/*Set<employee> set = new TreeSet(new Comparator() {
			@Override
			public int compare(Object o1, Object o2) {
				Employee emp1 = (Employee)o1;
				Employee emp2 = (Employee)o2;
				
				return emp1.getName().compareTo(emp2.getName());
			}
		});*/
		
		// 方式2:自定义类型实现Comparable接口
		Set<employee> set = new TreeSet<employee>();
		set.add(new Employee("wanghaijun"));
		set.add(new Employee("mayu"));
		set.add(new Employee("luxiangdong"));
		
		printSet(set);
	}
}</employee></employee></employee></employee></employee></employee></employee></string></string>


addItem方法:

第一个size是3

第二个是3,因为set.add("wanghaijun");跟前面重复了,

第三个是4,因为set.add(new String("liqiang"));跟前面重复了


HashSet的重复判断是这样的:

hashcode不同,对象一定不同

hashcode相同,判断==(比地址)

==不同,再比较equals


伪代码就是:hashcode()&&(==||equals()),满足此条件(hashcode相同并且(==,equals其中一个相同))就表明元素是相同的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值