超牛牪犇Java之Set集合

一.Set集合

特点:无序(没有下标) 不重复

这里对有序的定义是:按什么顺序存储 打印出来还是什么顺序

1.HashSet:去重的功能

example:无序:

//创建一个HashSet
//保存 f f a a b b d d
HashSet<String> set = new HashSet<>();
set.add("q");
set.add("q");
set.add("w");
set.add("w");
set.add("e");
set.add("e");
set.add("r");
set.add("r");
//迭代器遍历
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
	String next = iterator.next();
	System.out.println(next);
}
//增强for循环
for (String string : set) {
	System.out.println(string);
}

结果说明HashSet集合是无序的:

了解HashSet是怎么去重的:

//创建Set集合  保存六个人 两两重复
HashSet<Person> set = new HashSet<>();
set.add(new Person("小风",13));
set.add(new Person("小风",13));
set.add(new Person("张三",18));
set.add(new Person("张三",18));
set.add(new Person("李四",20));
set.add(new Person("李四",20));
//遍历集合
for (Person person : set) {
	System.out.println(person);
}

需要在Person类中重写equals方法和hashCode方法

先重写equals方法 发现equals方法未被调用

@Override
public boolean equals(Object obj) {
	Person person = (Person)obj;
	System.out.println("调用equals方法");
	return this.age == person.getAge() &&
	this.name.equals(person.getName());
}

然后重写hashCode方法:

@Override
public int hashCode() {
	System.out.println("精神可嘉阿迪吉萨");
	//返回一个固定值 让所有创建出来的Person对象 HashCode码都一样
	//返回固定值效率不高(equals每次都会被调用)
	return 10;
	//当添加到set中的对象 HashCode码不相同时,没有调用equals方法
	//并且对象直接存到set集合中
	//HashCode码相同时,会调用equals方法来查看是否是同一个对象,是就不存进去,不是就存进去
}

这时才会调用equals方法

因为只要创建对象就会给每一个对象分配一个HashCode码 当HashCode码相同时才会调用equals方法

看一下用系统直接生成的重写equals方法和hashCode方法:

@Override
public int hashCode() {
	//复杂度 是为了减少hashcode码重复
	//提高存储时候调用equals方法的效率
	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;
	Person other = (Person) 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;
}

example:

编写一个程序,获取10个1至20的随机数,要求随机数不能重复

HashSet<Integer> set = new HashSet<>();
while (set.size() < 10) {
	int random = (int)(Math.random()*(20 - 1 + 1) + 1);
	set.add(random);
}
System.out.println(set);
for (Integer integer : set) {
	System.out.println(integer);
}

去重系统类的对象的时候 不用重写equals方法和hashCode方法了

example:刷锅法:

利用set集合a , b , c , d 

去除ArrayList集合中的重复元素(操作原ArrayList)

ArrayList保存了a,a,b,b,c,c,d,d



ArrayList<String> list = new ArrayList<>();
	list.add("a");
	list.add("a");
	list.add("b");
	list.add("b");
	list.add("c");
	list.add("c");
	list.add("d");
	list.add("d");
HashSet<String> set = new HashSet<>();
	set.add("a");
	set.add("b");
	set.add("c");
	set.add("d");		
set.addAll(list);
//清空list集合
list.clear();
//把所有元素放回list中
list.addAll(set);
System.out.println(list

2.linkedHashCode:

linked表示有序(怎么存的 打印出来还是那个顺序)

3.TreeSet:排序的功能

先了解一下二叉树:

存储规则:

比我小的数放到我的左边 (返回负数的情况)

比我大的数放到我的右边 (返回正数的情况)

返回的是0 就不存储

输出的规则 以升序打印

TreeSet在存储的时候

只跟compareTo的返回值有关

看一下效果:

TreeSet<Integer> set = new TreeSet<>();
set.add(10);
set.add(7);
set.add(15);
set.add(19);
set.add(19);
set.add(9);
System.out.println(set);

example:

在一个集合ArrayList中存储了无序并且重复的字符串

要求 排序,而且还不能去除重复(用比较器)

主要按字符串长度比较 次要按字符比

先创建比较器 在比较器中写排序规则:

//创建比较器
class StringLengthImpl implements Comparator<String>{
        //实现比较器方法
        @Override
	public int compare(String o1, String o2) {
		// TODO Auto-generated method stub
		int length = o1.length() - o2.length();
		//主要按长度 次要按字符串
		int num = o1.compareTo(o2);
		int rel  = length  == 0 ? num : length;
		return rel == 0 ? 1 : rel;
	}
}

利用TreeSet的构造方法 直接将比较器的实现类传进去

ArrayList<String> list = new ArrayList<>();
		list.add("asdns");
		list.add("xsdns");
		list.add("xsdns");
		list.add("asdssans");
		list.add("dns");
		list.add("dns");
		list.add("assdsdaasddns");
		list.add("adasns");
		//创建一个TreeSet
		TreeSet<String> set = new TreeSet<>(new StringLengthImpl());
		set.addAll(list);
		list.clear();
		list.addAll(set);
		System.out.println(list);



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值