day15 Set集合
来源:互联网 发布:不用网络的三国游戏 编辑:程序博客网 时间:2024/06/05 05:22
对于Set集合来说,具体的类他是根据底层实现方式来构建的
List集合和Set集合的区别:
* Set:元素是唯一的,无序性(存储和取出不一致)
* List:元素可以重复,有序性(存储和取出一致)
一HashSet集合
1.1 如何不添加重复的元素
HashSet该集合包含的元素,必须重写HashCode()和equals()方法,(这些方法是在添加元素时候自动调用的)才可以保证元素的唯一不重复性,集合底层是用哈希表实现的,哈希表是一维数组,每个数组的元素又是由链表实现的,数组的下表是调用HashCode()方法得到的哈希值,在进行添加元素的时候,首先得到了元素的哈希值,根据哈希值确定数组的小标,然后调用equals()方法,比较内容是否相等,如果相等了,则元素重复。
注意: 自动生成的重写的方法 无法比较虽然内容一样,但是地址不一样的情况,所以要比较地址不一样,内容一样,就要改写equals()方法
提醒:字符串已经重写这两个方法
实例1:
Student类public class Student {private int age;private String name;public Student() { super(); // TODO 自动生成的构造函数存根}public Student(int age, String name) { super(); this.age = age; this.name = name;}public int getAge() { return age;}public void setAge(int age) { this.age = age;}public String getName() { return name;}public void setName(String name) { this.name = name;}@Overridepublic String toString() { return "Student [age=" + age + ", name=" + name + "]";}@Overridepublic int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result;}@Overridepublic boolean equals(Object obj) { if (this == obj) return true; if(this!=obj) if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) 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;}}
public class HashSetDemo1 { public static void main(String[] args) { HashSet<Student> hs=new HashSet<Student>(); Student s1=new Student(20, "王帅"); Student s2=new Student(21, "王帅"); Student s3=new Student(20, "王帅"); Student s4=new Student(20, "张帅"); //只有Student同时重写了HashCode()方法和equals()才会在添加的时候过滤重复的元素 hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); //如果Student 重写了hashCode()方法 只要内容一样,返回的值就一样, //如果没有重写,地址不一样,就会返回不一样的hash值 for(Student s:hs) System.out.println(s);//3个学生 }}
二TreeSet
1 如何实现元素的唯一:
TreeSet底层使用二叉树来实现的,在经行添加元素的时候,进行比较大小,但是如何经行比较大小呢,这时候就要用到比较器来进行比较
2 比较器 实现方式 one:
元素实现Comparable接口,然后重写compareTo()方法,自定义比较方法(如果想要全部添加元素,只需要在compareTo()方法里面返回一个非0数字即可 ,就可以重复添加元素
//实现接口public class Student2 implements Comparable<Student2>{private int age;private String name;public Student2() { super();}public Student2(int age, String name) { super(); this.age = age; this.name = name;}public int getAge() { return age;}public void setAge(int age) { this.age = age;}@Overridepublic int compareTo(Student2 o) { //重写的方法 如果年龄一样,就比较姓名的首字母顺序 字符串已经重写了compareto方法 int num1= this.age-o.age; int num2=num1==0?this.name.compareTo(o.name):num1; return num2;}@Overridepublic String toString() { return "Student2 [age=" + age + ", name=" + name + "]";}}
public class demo1 { public static void main(String[] args) { // TODO 自动生成的方法存根 TreeSet<Student2> ts=new TreeSet<Student2>(); Student2 s1=new Student2(18,"wang"); Student2 s2=new Student2(17,"wang"); Student2 s3=new Student2(18,"zhao"); Student2 s4=new Student2(18,"li"); Student2 s5=new Student2(18,"wangg"); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); for(Student2 s:ts) System.out.println(s); }}输出结果:Student2 [age=17, name=wang]Student2 [age=18, name=li]Student2 [age=18, name=wang]Student2 [age=18, name=wangg]Student2 [age=18, name=zhao]
比较器的实现方式two:
添加的元素类什么事情不用做,在实现创建集合类的时候去采用匿名内部类实现new Comparator比较方法
如: TreeSet st=new TreeSet(new Comparator() {
@Override //比较的方法体 } } );
需求:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
Student类 什么事情不用干public class Student { private String name; private int ChScore; private int EnScore; private int MaScore; private int CScore;public Student(String name, int chScore, int enScore, int maScore) { super(); this.name = name; ChScore = chScore; EnScore = enScore; MaScore = maScore;}public Student() { super(); // TODO Auto-generated constructor stub}public String getName() { return name;}public void setName(String name) { this.name = name;}public int getChScore() { return ChScore;}public void setChScore(int chScore) { ChScore = chScore;}public int getEnScore() { return EnScore;}public void setEnScore(int enScore) { EnScore = enScore;}public int getMaScore() { return MaScore;}public void setMaScore(int maScore) { MaScore = maScore;}public int getCScore() { CScore=this.ChScore+this.MaScore+this.EnScore; return CScore;}@Overridepublic String toString() { return "学生姓名:" + name +"\t"+ ", 语文成绩:" + ChScore +"\t"+ ", 英语成绩:" + EnScore + "\t"+", 数学成绩:" + MaScore +"\t"+"总成绩为:"+CScore+"\t";}}
public class Demo1 { public static void main(String[] args) { //录入学生成绩 TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {//采用了匿名内部类方法 public int compare(Student s1, Student s2) { //实现比较方法 int num1=s1.getCScore()-s2.getCScore(); //如果总成绩一样,比较语文成绩 int num2=num1==0?s1.getChScore()-s2.getChScore():num1; //如果语文成绩一样比较数学成绩 int num3=num2==0?s1.getMaScore()-s2.getMaScore():num2; //如果数学成绩还一样 比较英语成绩 int num4=num3==0?s1.getEnScore()-s2.getEnScore():num3; return num4; } }); //Scanner sc=new Scanner(System.in); /* * 本来是要输入3个学生的成绩,但是你只创建了一个键盘输入对象 * 所以 当你输入第二个学生信息时候,只会一直在录入第一个学生信息 */ for(int i=0;i<3;i++){ Scanner sc=new Scanner(System.in);// Student ss=new Student(); String s=sc.nextLine(); int chScore=sc.nextInt(); int EnScore=sc.nextInt(); int MaScore=sc.nextInt(); ss.setName(s); ss.setChScore(chScore); ss.setEnScore(EnScore); ss.setMaScore(MaScore); ts.add(ss); } for(Student s:ts){ System.out.println(); System.out.println(s); } }}
比较器实现方法three
思想:单独写一个比较器然后实现Comparator接口
例子:
//MyComparatpr是Comparator接口的子实现类public class MyComparator implements Comparator<Student> { @Override public int compare(Student s1, Student s2) {// return 0;// 按照学生姓名长度从小到大进行排序 //int num = this.name.lengt()-s.name.length(); //this--:s1 //s---:s2 int num = s1.getName().length() - s2.getName().length() ; //次要条件:姓名长度一样,还要比较姓名的内容是否一样 int num2 = num==0 ? s1.getName().compareTo(s2.getName()): num ; //姓名长度和内容都一样,还需比较两个人的年龄是否一样 int num3 = num2 ==0 ? s1.getAge() - s2.getAge() : num2 ; return num3 ; }}
Student什么事情不用干public class Student { private String name ; private int age ; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = 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; }}
随记:
1集合也重写了toString()方法,如果没有元素 输出[],
2 判断集合包含某元素contains(obj) 其实底层调用的是equals方法,所以判断包含的时候一定重写该方法
3不管是 TreeSet 还是HashSet 要想在内容一样的前提下,加入地址不一样的元素,都可以在equals()方法里面做文章
- day15 Set集合
- Day15—List集合、Queue集合、Set集合
- day15笔记-集合
- day15 集合(一)
- day15(集合)
- day15<集合框架>
- 黑马程序员-day15集合框架
- day15
- day15
- day15
- day15
- day15
- day15
- Day15
- day15
- Day15
- Day15
- day15
- 新路程------hi3516 tmp过小导致更新img失败
- PAT
- 简单的D0L-系统生成分形
- [绍棠] iOS不错的框架
- 自定义控件学习笔记(一)Canvas 的 drawXXX() 系列方法
- day15 Set集合
- springMVC基本环境配置
- CSS实现垂直居中的常用方法
- java.lang.System.arraycopy()方法使用说明
- mysql修改表结构(alter table),多列/多字段
- Android中WindowManager类详解
- 机器学习算法与Python实践(1)
- ModelAndView 详解
- JAVA IO中的设计模式