Set汇合
不蕴含反复元素;没有带索引的办法,所以不能应用一般for循环遍历
set是一个接口不能间接实例化,得找它的实现类
set汇合存储字符串并遍历
HashSet:对汇合的迭代程序不做任何保障
Set<String> set = new HashSet<String>();//创立汇合对象//增加元素set.add("Hello");set.add("World");set.add("java");//增加元素 不蕴含反复元素的汇合set.add("World");//遍历 加强for循环for(String s : set){sout(s);}
输入程序不一样,就是因为HashSet不能保障迭代程序
哈希值
是JDK依据对象的地址或者字符串或者数字算进去的int类型的数值
Object类种有一个办法能够获取对象的哈希值
Student s1 = new Student(name:"林青霞",age:30);//创立一个学生对象//通过对象调用hashCode办法失去哈希值sout(s1.hashCode());sout(s1.hashCode());Student s2 = new Student(name:"林青霞",age:30);//创立一个学生对象sout(s2.hashCode());
同一个对象屡次调用hashCode()办法返回的哈希值是雷同的
即使成员变量是雷同的,然而因为对象不同所以默认状况下哈希值也是不同的,因为如果重写hashCode办法,返回默认值变成一样的,那输入的就是一样的了
通过办法重写,能够实现不同对象的哈希值是雷同的
不同对象的哈希值不同,雷同对象的哈希值雷同
这两个对象的哈希值雷同是因为字符串重写了object的hashCode办法
HashSet汇合概述和特点
在util包下
HashSet<String> hs = new HashSet<String>();//创立汇合对象//增加元素,没有索引hs.add("Hello");hs.add("World");hs.add("java");//遍历 加强for循环for(String s : hs){sout(s);}
HashSet汇合保障元素唯一性源码剖析
常见数据结构之哈希表
HashSet汇合无参构造方法默认汇合初始长度是16,而后对数据的哈希值对16取余,余数是多少就寄存在哪个地位,首先hello先寄存在2地位,而后发现world也须要寄存在2地位,而后两者的哈希值不一样,所以造成链表,而后java要和2地位的两个元素别离比拟哈希值发现不同,造成链表;前面那个world也是2地位,须要和后面三个进行比拟,发现和第一个哈希值不同,而后和第二个比发现和后面的world哈希值雷同,而后及比拟内容,发现内容也雷同,从而断定为先雷同元素,不进行存储
通话元素寄存在3地位,而后对重地元素进行剖析,发现也须要放在3地位,3地位有元素,所以须要和通话元素进行哈希值比拟,发现哈希值雷同,当哈希值雷同时就须要对内容荣进行比拟,而后对他们的内容进行比照,发现内容不雷同,所以重地元素也能够存储进来造成链表
案例 HashSet汇合存储学生并遍历
HashSet<Student> hs = new HashSet<Student>();//创立HashSet汇合对象Student s1 = new Student(name:"林青霞",age:30);//创立一个学生对象Student s2 = new Student(name:"张曼玉",age:35);//创立一个学生对象Student s3 = new Student(name:"王祖贤",age:33);//创立一个学生对象//s3和s4成员变量值雷同,依照要求就认为是同一个对象,所以s4就应该存储不进去Student s4 = new Student(name:"王祖贤",age:33);//创立一个学生对象//把学生增加到汇合hs.add(s1);hs.add(s2);hs.add(s3);hs.add(s4);//遍历 加强for循环for(Student s : hs){sout(s.getName() + "," + s.getAge());
然而依照下面的的代码s4是增加胜利的了,所以须要进行批改能力保障元素的唯一性
所以Student类须要重写HashCode办法和equals办法,而后就保障唯一性了
LinkedHashSet汇合概述和特点
是由哈希表和链表实现的Set接口,具备可预测的迭代程序
由链表保障元素有序,也就是说元素的存储和去除程序是统一的
LinkedHashSet 存储字符串并遍历
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();//创立汇合对象//增加元素linkedHashSet.add("Hello");linkedHashSet.add("World");linkedHashSet.add("java");//增加元素 不蕴含反复元素的汇合linkedHashSet.add("World");//遍历 加强for循环for(String s : linkedHashSet){sout(s);}
TreeSet汇合概述和特点
间接的实现了Set接口
TreeSet 存储整数并遍历
汇合里存储的是援用类型,所以存储整数应该用她的包装类Interger
TreeSet<Interger> ts = new TreeSet<Interger>();//创立汇合对象//增加元素 主动装箱ts.add(10);ts.add(40);ts.add(30);ts.add(50);ts.add(20);//增加元素 不蕴含反复元素的汇合ts.add(30);//调用的是无参结构 所以是天然排序,是从小到大//遍历 加强for循环for(Interger i : ts){sout(i);}
天然排序Comparable的应用
TreeSet<Student> ts = new TreeSet<Student>();//创立HashSet汇合对象Student s1 = new Student(name:"xishi",age:29);//创立一个学生对象Student s2 = new Student(name:"wangzhaojun",age:28);//创立一个学生对象Student s3 = new Student(name:"diaochan",age:30);//创立一个学生对象Student s4 = new Student(name:"yangyuhuan",age:33);//创立一个学生对象//s4和s5成员年龄雷同Student s5 = new Student(name:"linqingxia",age:33);//创立一个学生对象//把学生增加到汇合ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);//遍历 加强for循环for(Student s : ts){sout(s.getName() + "," + s.getAge());
出现异常
是因为如果要做天然排序就得让类实现该接口,因为该接口能够对类的对象进行排序,所以须要让学生类实现Comparable这个接口,而后重写这个接口外面的办法compareTo
因为重写的compareTo办法返回的是0,所以在增加第二个 第三个 第四个元素的时候就会认为和第一个是同一个元素,所以增加不上,返回值是0,阐明元素是相等的,反复的就不会存储。
改成return 1;阐明s2比s1大,s3比s2大,s4比s3大,就能够增加,而后依照从小到大的程序输入,也就是正序
改成return -1;阐明s2比s1小,s3比s2小,s4比s3小,就能够增加,而后依照从小到大的程序输入,也就是倒序
返回是0,就认为是反复的相等的不增加;返回是正数,就认为是前面的小,也就是顺叙存储;返回是负数,就认为是前面的大,也就是升序存储
题目要求依照年龄从小到大排序,依照姓名的字母程序排序
也就是说要改良重写的compareTo办法的返回值
办法外部其实自身就有这个属性,拿s1 s2举例来看,s1不须要和他人比,s2须要和s1比,这个this就是s2,这个s就是s1
用前面的age减去后面的,返回差值,就是升序,也就就是从小到大;用后面的age减去前面的,返回差值,就是降序,也就是从大到小
当年龄一样的时候返回0,就存储不进来,然而依照题目要求要用名字首字母排序,所以进行更改
字符串自身能够自行排序
TreeSet<Student> ts = new TreeSet<Student>();//创立HashSet汇合对象Student s1 = new Student(name:"xishi",age:29);//创立一个学生对象Student s2 = new Student(name:"wangzhaojun",age:28);//创立一个学生对象Student s3 = new Student(name:"diaochan",age:30);//创立一个学生对象Student s4 = new Student(name:"yangyuhuan",age:33);//创立一个学生对象//s4和s5成员年龄雷同Student s5 = new Student(name:"linqingxia",age:33);//创立一个学生对象//s6和s5成员姓名年龄都雷同Student s6 = new Student(name:"linqingxia",age:33);//创立一个学生对象//把学生增加到汇合ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);ts.add(s6);//遍历 加强for循环for(Student s : ts){sout(s.getName() + "," + s.getAge());
int num = this.age - s.age;int num1 = num == 0?this.name.compareTo(s.name):num//当年龄雷同的时候就返回this.name.compareTo(s.name),当年龄不同的时候就返回numrenturn num1;
天然排序Comparator的应用
带参结构,也就是指定比拟器的形式,依照年龄从小到大排序
传递了一个比拟器接口
//创立HashSet汇合对象匿名外部类形式 上面会主动重写conpare办法TreeSet<Student> ts = new TreeSet<Student>(**new Comparator<Student>({ @Override public int compare(Student s1,Student s2){ //这个办法外部的this代表的是TreeSet而不是学生,所以办法的参数传了两个学生对象 //年龄从小到大排序 //this.age - s.age //**s1是this s2是s** int num = s1.getAge()-s2.getAge();//在这里不能拜访学生类的公有成员 int num1 = num == 0?s1.getName().compareTo(s2.getName()):num return num1; }}**);Student s1 = new Student(name:"xishi",age:29);//创立一个学生对象Student s2 = new Student(name:"wangzhaojun",age:28);//创立一个学生对象Student s3 = new Student(name:"diaochan",age:30);//创立一个学生对象Student s4 = new Student(name:"yangyuhuan",age:33);//创立一个学生对象//s4和s5成员年龄雷同Student s5 = new Student(name:"linqingxia",age:33);//创立一个学生对象//s6和s5成员姓名年龄都雷同Student s6 = new Student(name:"linqingxia",age:33);//创立一个学生对象//把学生增加到汇合ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);ts.add(s6);//遍历 加强for循环for(Student s : ts){sout(s.getName() + "," + s.getAge());
Set案例 问题排序
通过比拟器进行排序实现
s1呈现在后面是从低到高,s2呈现在后面是从高到低
总分雷同依照语文问题升序进行
当总分和单科分数都一样时,依照名字从小到大排序
@Override public int compare(Student s1, Student s2) { // 升序 return s1.getAge()-s2.getAge(); return s1.getAge().compareTo(s2.getAge()); // 降序 return s2.getAge()-s1.getAge(); return s2.getAge().compareTo(s1.getAge());
参考网址 comparable和comparator的区别
http://www.manongjc.com/artic...
Comparator和Comparable的区别
Comparable:本人(this)和他人(参数)比拟,本人须要实现Comparable接口,重写比拟的规定compareTo办法 Comparator:相当于找一个第三方的裁判,比拟两个 Comparator的排序规定: o1-o2:升序 Comparable接口的排序规定: 被排序的汇合里边存储的元素,必须实现Comparable,重写接口中的办法compareTo定义排序的规定 public class Person implements Comparable<Person>{ 本人(this)-参数:升序
Set案例 不反复的随机数
//创立HashSet汇合对象Set<Integer> set = new HashSet<Integer>();//创立随机数对象Random r = new Random();//判断汇合的长度是不是小于10while(set.size()<10){ //产生一个随机数增加到汇合1-20之间 int number = r.nextInt(bound:20)+1; set.add(number);//有反复的无奈增加进去//遍历 加强for循环for(Integer i : set){sout(i); }
改成TreeSet汇合
//创立TreeSet汇合对象Set<Integer> set = new TreeSet<Integer>();
会进行从小到大的排序