关于java:Set集合-笔记

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>();

会进行从小到大的排序

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理