13.无序集合

无序集合

​ 无序:展示顺序与存储顺序不一致

​ 不能保存重复数据

​ 重复数据:基本数据类型、String类型 值相同 就是重复数据

​ 引用数据类型:默认比较地址 采用父类的hashCode()

​ 可以通过重写去重的方法【equals() hashCode()】来实现忽略地址 只比较属性值

java中是如何实现真正的去重:通过equals() hashCode()两个方法联合使用

Object的hashCode():表示在哈希表中的位置 根据所存储的物理地理位置通过一定算法获取 整数

Object的toString():返回字符串中@后的内容就是当前对象通过hashCode()获取的整数的十六进制表示形式

		User u1 = new User("gasdf",18);
		
		System.out.println(u1.hashCode());			//98127626
		System.out.println(u1);						//com.woniuxy.demo1.User@5d94f0a

案例:

​ User自定义类型 String name int age

​ 创建HashSet 保存User对象 只要是new的新对象 都认为是不同数据 跟name age是否相同无关

​ 现在希望忽略地址 只要属性值都相同 则认为是重复数据 不让HashSet存储

​ 可以重写hashCode() 和 equals()

public class User {

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

	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
    //通过快捷键shift+alt+s 生成hashCode()和equals()方法关于属性的重写
    @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;
	}
	
}
		//测试类中
		User u1 = new User("gasdf",18);
		User u2 = new User("gasdf",18);
		User u3 = new User("gasdf",18);
		User u4 = new User("gasdf",18);
		User u5 = new User("gasdf",18);
		User u6 = u1;
		
		//HashSet集合 存储元素时 会根据hashCode()和equals()来判定是否是重复数据
		HashSet<User> hu = new HashSet<User>();
		hu.add(u1);
		hu.add(u2);
		hu.add(u3);
		hu.add(u4);
		hu.add(u5);
		hu.add(u6);
		hu.add(u1);
		
		for(User u : hu) {
			System.out.println(u);
            //如果没有重写去重方法 则有5个数据 
            //如果重写了去重方法 则只有1个数据
		}
HashSet

​ 基本数据类型、String 已经重写了去重方法 可以自动去重

​ 自定义类型:重写去重方法【hashCode() equals()】

​ 比较器失效—》无序集合 不能通过Collections.sort()进行排序 可以转成有序集合

LinkedHashSet

​ HashSet的子实现类

​ 每个元素另外保存有下个元素的地址(多了一根保留顺序的链条) --》展示顺序与存储顺序一致 依然没有索引

​ 基本数据类型、String 已经重写了去重方法 可以自动去重

​ 自定义类型:重写去重方法【hashCode() equals()】

​ 比较器失效—》无序集合 不能通过Collections.sort()进行排序 可以转成有序集合

TreeSet 存储的数据类型 必须实现了比较器接口 否则存储失败

​ 存储数据时 会根据比较器 判断两个元素是否相同及先后顺序(比较器实现去重和排序两个功能)

​ 基本数据类型、String类型 直接存储 默认去重

​ 自定义类型:去重依赖比较器 如果两个元素通过比较器判断返回0 则认为是重复数据 会执行去重

​ 反之 即使两个元素地址 属性值都相同 如果比较返回非0 则认为是不同数据 都会存储

public class User implements Comparable<User>{
	String name;
	int age;
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
//	@Override
//	public String toString() {
//		return "User [name=" + name + ", age=" + age + "]";
//	}
	@Override
	public int compareTo(User o) {
		// TODO Auto-generated method stub
		return -1;//逆序存储 全都能存入
        //return 1;//顺序存储  全都能存入
        //return 0;//只能存入第一个元素 后续都被判断为重复元素
	}
}		

		User u1 = new User("abc",17);
		User u2 = new User("ggc",16);
		User u3 = new User("xsc",18);
		User u4 = new User("abc",22);
		User u5 = new User("abc",17);
		User u6 = new User("tec",17);
		User u7 = u1;
		TreeSet<User> tu = new TreeSet<User>();
		tu.add(u1);//若User类没有实现比较器接口  则存储失败 报出ClassCastException异常
		tu.add(u2);
		tu.add(u3);
		tu.add(u4);
		tu.add(u5);
		tu.add(u6);
		tu.add(u7);//如果实现的比较器固定返回1  则即使地址相同 属性值相同的两个对象 都能存储
		System.out.println(tu.size());
		
		for(User u : tu) {
			System.out.println(u);
		}

案例:

​ 存储两个值相同的字符串

​ HashSet 不能存储相同值的String 是因为String类 重写了 hashCode() 和 equals()方法

​ TreeSet 不能存储相同值的String 是因为String实现了Comparable接口 相同值的String会返回0

//String 已有内部比较器规则 相同的值会返回0
//只有通过外部比较器 覆盖原有比较规则
public class StringCom implements Comparator<String> {
	@Override
	public int compare(String o1, String o2) {
		// TODO Auto-generated method stub
		return 1;
	}
}
//使用外部比较器 创建TreeSet对象时 将外部比较器对象传入构造方法
		TreeSet<String> ts = new TreeSet<String>(new StringCom());
		
		ts.add("abc");
		ts.add("abc");
		ts.add("abc");
		ts.add("abc");
		ts.add("dfg");
		ts.add("abc");
		
		for(String s : ts) {
			System.out.print(s+" ");
		}
		//abc abc abc abc dfg abc 
总结:

​ 有序列表:可以存储重复数据 可以通过Collections使用比较器来排序

​ 无序集合:

​ String、基本数据类型 都默认去重

​ HashSet:所有类型都不可排序 自定义类型 通过hashCode() 和equals()去重

​ TreeSet:所有类型都可通过比较器排序 自定义类型 通过比较器是否返回0去重

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值