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),当年龄不同的时候就返回num
renturn 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();
//判断汇合的长度是不是小于10
while(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>();
会进行从小到大的排序
发表回复