J2EE基础 02(集合框架之Set)

目录

【思维导图】

一、Set的特点

①不可重复 

②无序       

二、Set集合的遍历方式

三、HashSet哈希表存储、重复元素存储底层探究

四、TreeSet(自然排序、比较排序)

①自然排序

②比较器排序


【思维导图】


一、Set的特点

①不可重复 

 解释:“李四”增加了两次,但输出结果时只有一个“李四”。

②无序       

解释:增加时的顺序为:张三——李四——王二——麻子

           输出时为:李四——张三——麻子——王二

代码块展示:

package com.chenchen.set;

import java.util.HashSet;
import java.util.Iterator;

/**
 * 
 * Set集合的特点:
 * 	①不重复:基本数据类型 String = "abc";(如果是引入对象类型的话就是可以重复的 String= new String())
 * 	②无序
 * 
 * @author ChenChen
 *@date 2022年6月8日 下午4:41:02
 */
public class Demo1 {
	public static void main(String[] args) {
		HashSet<Object> set = new HashSet<>();
		set.add("张三");
		set.add("李四");
		set.add("王二");
		set.add("麻子");
		set.add("李四");
		System.out.println(set.size());//打印set集合长度
		
		System.out.println("=======增强for=====");
		for (Object object : set) {//循环遍历
			System.out.println(object);
		}
		
		System.out.println("=======迭代器=====");
		Iterator<Object> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
	
}

输出结果:

=======增强for=====
李四
张三
麻子
王二
=======迭代器=====
李四
张三
麻子
王二

注意:

之所以输出的结果不存在重复的情况,是因为存的是基本数据类型的值(eg:String ="张三";),如果存的值是引入对象类型的话就是可以重复的 (eg:String= new String();)。

可以重复情况下:代码展示:

package com.chenchen.set;

import java.util.HashSet;
import java.util.Iterator;

/**
 * @author ChenChen
 *@date 2022年6月8日 下午6:02:42
 */
public class Demo2 {

	public static void main(String[] args) {
		HashSet<Object> set = new HashSet<>();
        //实例化一个对象
		set.add(new Person("麻子",18));
		set.add(new Person("张三",33));
		set.add(new Person("李四",14));
		set.add(new Person("王二",16));
		set.add(new Person("麻子",18));
		System.out.println(set.size());//打印set集合长度 集合容量为5
		Iterator<Object> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());//打印结果
		}
	}
}
}

输出结果:

二、Set集合的遍历方式

代码块展示:

package com.chenchen.set;

import java.util.HashSet;
import java.util.Iterator;

/**
 * 
 * set底层去重复原理
 * 1.set去重底层原理是与对象的hashcode以及equals方法有关
 * 2.判断重复元素的时候,是先比较hashcode的值,在调用equals进行比较内容
 * 
 * @author ChenChen
 *@date 2022年6月8日 下午6:02:42
 */
public class Demo2 {

	public static void main(String[] args) {
		HashSet<Object> set = new HashSet<>();
		set.add(new Person("麻子",18));
		set.add(new Person("张三",33));
		set.add(new Person("李四",14));
		set.add(new Person("王二",16));
		set.add(new Person("麻子",18));
		System.out.println("set集合的长度:"+set.size());//打印set集合长度
		
		System.out.println("=======迭代器=====");
		Iterator<Object> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

	
//创建一个实体类
class Person /*implements Comparable<Person>*/{
	private String name;
	private int age;
	private int level;
	
	public Person(String name, int age, int level) {
		super();
		this.name = name;
		this.age = age;
		this.level = level;
	}
	public int getLevel() {
		return level;
	}
	public void setLevel(int level) {
		this.level = level;
	}
	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 Person() {
		// TODO Auto-generated constructor stub
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", level=" + level + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return 1;//如果result定义为1时,那么就会调用
	}
	@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;
	}
}
	
	

输出结果:

Person [name=麻子, age=18, level=0]
Person [name=张三, age=33, level=0]
Person [name=李四, age=14, level=0]
Person [name=王二, age=16, level=0]


三、HashSet哈希表存储、重复元素存储底层探究

代码块展示:


package com.chenchen.set;

import java.util.HashSet;
import java.util.Iterator;

/**
 * 
 * set底层去重复原理
 * 1.set去重底层原理是与对象的hashcode以及equals方法有关
 * 2.判断重复元素的时候,是先比较hashcode的值,在调用equals进行比较内容
 * 
 * @author ChenChen
 *@date 2022年6月8日 下午6:02:42
 */
public class Demo2 {

	public static void main(String[] args) {
		HashSet<Object> set = new HashSet<>();
		set.add(new Person("麻子",18));
		set.add(new Person("张三",33));
		set.add(new Person("李四",14));
		set.add(new Person("王二",16));
		set.add(new Person("麻子",18));
		System.out.println(set.size());//打印set集合长度
		
		System.out.println("=======迭代器=====");
		Iterator<Object> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

	
//创建一个实体类
class Person{
	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 Person() {
		// TODO Auto-generated constructor stub
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int hashCode() {
		System.out.println("=====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) {
		System.out.println("=====equals=======");
		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;
	}	
}

输出结果:

解释:

之所以调用了5次hashcode方法是因为存了5个值进去;调用了1次equals方法是因为将所有值进行比较,找出了含有1个重复的值,调用equals方法将其去除。所以最后的set集合的长度为4,输出的结果不存在重复的情况。


四、TreeSet(自然排序、比较排序)

①自然排序

代码块展示:

package com.chenchen.set;

import java.util.TreeSet;

/**
 * Set集合排序
 * 
 * @author ChenChen
 *@date 2022年6月8日 下午8:20:26
 */
public class Demo3 {
	public static void main(String[] args) {
		TreeSet set = new TreeSet<>();
		set.add("2");
		set.add("9");
		set.add("5");
		set.add("6");
		set.add("3");
		set.add("8");
		for (Object object : set) {
			System.out.println(object);
		}
	}
}

输出结果:

 错误演示:

package com.chenchen.set;

import java.util.TreeSet;

/**
 * Set集合排序
 * 
 * @author ChenChen
 *@date 2022年6月8日 下午8:20:26
 */
public class Demo3 {
	public static void main(String[] args) {
		/**
		 * 提问环节:
		 * 从xxx公司,拿到用户数据,需要根据用户的级别,进行会议座位的排序
         *eg:
		 * 张三 部门总监 1
		 * 李四 普通员工 3
		 * 麻子 部门经理 2
		 * 
		 * 现象:
		 * 1.String默认是能够排序的
		 * 2.自定义的对象无法排序,报类型转换异常
		 */
//		Exception in thread "main" java.lang.ClassCastException:
//		com.chenchen.set.Person cannot be cast to java.lang.Comparabley 意思是:Person类不能直接转换为Comparable接口

		TreeSet set = new TreeSet<>();
		set.add(new Person("张三",18,1));
		set.add(new Person("王二",15,4));
		set.add(new Person("麻子",20,2));
		set.add(new Person("李四",20,3));
		for (Object object : set) {
			System.out.println(object);
		}
	}
}

解释

String默认是能够排序的原因是因为String在底层代码里实现了Comparable接口,但是自定义的对象无法排序,报类型转换异常

如果想让自定义对象实现排序就要将该对象的类实现Comparable接口。代码展示:

package com.chenchen.set;

import java.util.HashSet;
import java.util.Iterator;

/**
 * 
 * @author ChenChen
 *@date 2022年6月8日 下午6:02:42
 */
public class Demo2 {
//创建一个实体类
class Person implements Comparable<Person>{
	private String name;
	private int age;
	private int level;
	
	public Person(String name, int age, int level) {
		super();
		this.name = name;
		this.age = age;
		this.level = level;
	}
	public int getLevel() {
		return level;
	}
	public void setLevel(int level) {
		this.level = level;
	}
	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 Person() {
		// TODO Auto-generated constructor stub
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Person o) {
		// TODO Auto-generated method stub
		return this.level - o.level;
	}
}

注意:

 输出结果:

 Person [name=张三, age=18]
Person [name=麻子, age=20]
Person [name=李四, age=20]
Person [name=王二, age=15]

增加时的顺序:张三——王二——麻子——李四

输出时的顺序:张三——麻子——李四——王二

按照属性值level排序,排序成功!

②比较器排序

代码块展示:

ok,本章内容分享完毕,下期预告Map集合知识点,若本文章内容出现错误,还望指正。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值