Java学习日记:set集合(不多用)

set集合

Set接口:存储无序的,不可重复的数据,没有索引,不能使用普通for循环遍历,无下标,底层实际 上是HashMap(数组+链表+红黑树)

三个主实现类

🌟HashSet:作为Set接口的主要实现类,线程不安全,可以存储null值

🌟LinkedHashSet :作为HashSet的子类,遍历其内部数据,可以按照添加的顺序遍历 对于频繁 遍历操作,LinkedHashSet效率高于HashSet,用的不多,保证存入和取出的顺序一样

🌟TreeSet:可以按照添加对象的指定属性,进行排序

Hashset:

🔷HashSet:作为Set接口的主要实现类,线程不安全,可以存储null值

🔷HashSet是Set的主实现类,HashSet按hash算法来存储集合中的元素,具有很好的存储,查找, 删除性能

🍉HashSet具有以下特点

💫不能保证元素的排列顺序 💫HashSet不是线程安全的 💫集合元素可以为空

🍉底层数据结构是哈希表

🍉对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致

🍉没有索引,所以不能使用普通for循环遍历

🍉由于是Set集合,所以是不包含重复元素的集合(去重)

set集合中使用自建的对象时需要注意的

🌟Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法

🌟要求:向Set中添 加的数据,其所有的类一定要重写hashCode()和equals()

🌟要求:重写hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码(哈 希值)

1 public class User {
2 private String name;
3 private int age;
4
5 public User() {
6 }
7
8 public User(String name, int age) {
9 this.name = name;
10 this.age = age;
11 }
12
13 public String getName() {
14 return name;
15 }
16
17 public void setName(String name) {
18 this.name = name;
19 }
20
21 public int getAge() {
22 return age;
23 }
24
25 public void setAge(int age) {
26 this.age = age;
27 }
28
29 @Override
30 public String toString() {
31 return "User{" +
32 "name='" + name + '\'' +
33 ", age=" + age +
34 '}';
35 }
36
37 @Override
38 //传入的对象默认为Object类型,此处涉及到多态
39 public boolean equals(Object o) {
40 //若参与比较的两个对象是同一个对象(地址值相同),直接返回true,只是为了提高代码执行效率
41 System.out.println("equals...................");
42 if (this == o) return true;
 //若传入的参数o是null或者不是user类型,直接返回false,此处使用了反射技术来判断o是否是
user类型
43
44 if (o == null || getClass() != o.getClass()) return false;
45 //使用向下转型,将Object类型的o转化为user类型的o。这是因为在传入时使用了多态,
46 //多态不能使用子类特有的属性和方法
47 User user = (User) o;
48 //若两个对象的name和age都相同,返回true,否则返回false
49 return age == user.age &&
50 Objects.equals(name, user.name);
51 }
52
53 @Override
54 public int hashCode() {
55 return Objects.hash(name, age);
56 }
57 }

🔷TreeSet介绍:

🍉可以按照添加对象的指定属性,进行排序

1,向TreeSet中添加数据,要求是相同类的对象

2,两种排序方式:自然排序(Comparable)和定义排序(Comparator)

3,自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals();

4,定义排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals(); 默认使用自然排序

自然排序(对象两属性)

第一种compareto方法的格式

@Override
55 public int compareTo(Object o) {
56 if (o instanceof User){
57 User user = (User)o;
58 //return this.name.compareTo(user.name);
59
60 //如果想从大到小怎么做?
61 //return -this.name.compareTo(user.name);
62
63 //想添加进去,根据年龄来比较
64 int compare = -this.name.compareTo(user.name);
65 if (compare != 0){
66 return compare;
67 }else {
68 return Integer.compare(this.age,user.age);
69 }
70 }else {
71 throw new RuntimeException("输入的类型不匹配");
72 }
73
74 }
75 }

 第二种compareto方法的格式

//按照姓名从大到小排序,按照年龄从小到大
2 @Override
3 public int compareTo(Object o) {
4 //instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例
5 //instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。
 //instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回
boolean 的数据类型。
6
7 if (o instanceof User){
8 User user = (User)o;
9 //return this.name.compareTo(user.name); //从小到大
10 //return -this.name.compareTo(user.name); //从大到小
11 int compareTo = -this.name.compareTo(user.name);
12 if (compareTo != 0){
13 return compareTo;
14 }else {
15 return Integer.compare(this.age,user.age);
16 }
17 }else {
18 throw new RuntimeException("输入的类型不匹配");
19 }
20 }

对象类去实现compareto方法,剩下都是最基本的,调试类光添加数据以及输出

public class User implements Comparable 

 自定排序

public class Demo7 {
2 public static void main(String[] args) {
3 //Comparator接口
4 Comparator com = new Comparator() {
5 //按照年龄排序
6 @Override
7 public int compare(Object o1, Object o2) {
8 //前升序 后倒序
9 if (o1 instanceof User && o2 instanceof User){
10 User user1 = (User)o1;
11 User user2 = (User)o2;
12 //return Integer.compare(user1.getAge(),user2.getAge());
 return Integer.compare(user2.getAge(),user1.getAge()); 
 
13
14 }else {
15 throw new RuntimeException("输入类型不匹配");
16 }
17 }
18 };
19
20 //TreeSet加参数:定义排序 不加就是自然排序
21 TreeSet set = new TreeSet(com);
22 set.add( new User("tom",19));
23 set.add( new User("Am",20));
24 set.add( new User("jk",18));
25 set.add( new User("Bm",16));
26 set.add( new User("Bm",17));
27
28 for (Object o : set) {
29 System.out.println("o = " + o);
30 }
31 }
32 }

作业案例

对象类

import java.util.Objects;

public class Woman{
    private String name;
    private int age;
    private int score;

    public Woman() {
    }

    public Woman(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    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 int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Woman woman = (Woman) o;
        return age == woman.age &&
                score == woman.score &&
                Objects.equals(name, woman.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, score);
    }

    @Override
    public String toString() {
        return name+"-"+age+"-"+score+"  ";
    }

}

执行类

import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;

public class Demo14 {
    //4,有5个学生对象,如下{"lucy", 28, 98},{"lily", 23, 97},
    //    // {"robt", 25, 100},{"wily", 15, 100},{"klin", 29, 93},
    //    //分别表示的是学生的姓名,年龄和分数.现要按学生成绩进行降序,
    //    // 如果成绩相同那么就按年龄进行升序
    //    //输出格式如下:wily-15-100 robt-25-100 lucy-28-98
    //    // lily-23-97 klin-29-93
    public static void main(String[] args) {
        TreeSet<Woman> set = new TreeSet<>(new Comparator<Woman>() {
            @Override
            public int compare(Woman o1, Woman o2) {
                if (o1 instanceof Woman && o2 instanceof Woman){
                    Woman w1 = (Woman)o1;
                    Woman w2 = (Woman)o2;
                    int best = Integer.compare(o2.getScore(),o1.getScore());
                    int best2 = Integer.compare(o1.getAge(),o2.getAge());
                    best = best == 0 ? best2 : best;
                    return best;
                }
                else {
                    throw new RuntimeException();
                }
            }
        });
        set.add(new Woman("lucy", 28, 98));
        set.add(new Woman("lily", 23, 97));
        set.add(new Woman("robt", 25, 100));
        set.add(new Woman("wily", 15, 100));
        set.add(new Woman("klin", 29, 93));

        Iterator<Woman> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.print(iterator.next());
        }
    }
}

对treeset的理解

两种比较方式小结

自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序

比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方 法,根据返回值进行排序

在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排 序

两种方式中关于返回值的规则

如果返回值为负数,表示当前存入的元素是较小值,存左边

如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存

如果返回值为正数,表示当前存入的元素是较大值,存右边

总结

set:三无人员:无下标 无重复 无序

list:三有人员:有下标 有重复 有序

HashSet:一定要写equals和Hashcode;

TreeSet:只能添加相同的对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值