Set

HashSet,LinkedHashSet,TreeSet

1.HashSet

注意事项2:千万不要设置set修改hashset属性值,很可能就不满足不重复的特性了

/*
HashSet:
概述:
    底层数据结构是哈希表
    它不保证迭代顺序,特别是它不保证该顺序恒久不变 (无序的)。
    允许存储 null 元素。
    不同步
 */
public class HashSetDemo1 {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("allen");
        set.add("beyonce");
        set.add("catalina");
        set.add("diana");
        set.add("allen");
        set.add("allen");
        set.add(null);
        set.add(null);
        set.add(null);
        System.out.println(set);
    }
}


/*
构造方法:
    HashSet():数组大小默认为16,加载因子默认为0.75f
    HashSet(Collection<? extends E> c)
    HashSet(int initialCapacity):
        JDK中HashMap数组的大小是2^n,所以数组的大小为大于等于initialCapacity的最小的2^n
        加载因子:0.75f
    HashSet(int initialCapacity, float loadFactor)
 */
public class HashSetDemo2 {
    public static void main(String[] args) {
        // HashSet set = new HashSet();
        // HashSet set = new HashSet(20);
        // HashSet set = new HashSet(20, 10f);

        // HashSet(Collection<? extends E> c)
        /*List<Character> list = Arrays.asList('A', 'A', 'B', 'B', 'C');
        HashSet<Character> set = new HashSet<>(list);
        System.out.println(set);*/
    }
}
/*
HashSet 是如何保证元素的唯一性的呢?
Set存储的元素是作为Map的key,而Map的key是唯一的

它依赖于存储元素的两个方法: int hashCode() & boolean equals(Object obj)
练习:
    HashSet存储自定义对象Student(name, age)
    如果name和age都相等,那么我们就认为两个对象相等。

注意事项:千万不要修改 HashSet 元素的属性值!
 */
public class HashSetDemo3 {
    public static void main(String[] args) {
        HashSet<Student> set = new HashSet<>();
        Student s1 = new Student("刘亦菲", 16);
        Student s2 = new Student("刘亦菲", 16);
        Student s3 = new Student("刘亦菲", 16);
        Student s4 = new Student("小龙女", 22);
        Student s5 = new Student("花木兰", 18);
        Student s6 = new Student("赵灵儿", 17);
        set.add(s1);
        set.add(s2);
        set.add(s3);
        set.add(s4);
        set.add(s5);
        set.add(s6);
        /*System.out.println(s1.equals(s2));
        System.out.println(s1.equals(s3));*/

        /*System.out.println(set.size()); // 4
        System.out.println(set);*/

        // 修改s4的属性值
        s4.setName("刘亦菲");
        s4.setAge(16);
        System.out.println(set.size()); // ?
        System.out.println(set);
    }
}

重写了equals也一定要重写hashCode方法

package com.cskaoyan.set;

import java.util.Objects;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

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

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Student s = (Student) obj;
        return age == s.age && Objects.equals(name, s.name);
    }

    @Override
    public int hashCode() {
        int h = 0;
        h = h * 31 + age;
        h = h * 31 + Objects.hashCode(name);
        return h;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2.TreeSet

public class TreeSetDemo1 {
    public static void main(String[] args) {
        //  TreeSet()
        TreeSet<Teacher> set = new TreeSet<>();
        Teacher t1 = new Teacher("风华大叔", 38);
        Teacher t2 = new Teacher("蓝胖", 88);
        Teacher t3 = new Teacher("严汉", 20);
        Teacher t4 = new Teacher("张帅", 19);
        Teacher t5 = new Teacher("黑大帅", 18);
        Teacher t6 = new Teacher("黑大帅", 18);

        set.add(t1);
        set.add(t2);
        set.add(t3);
        set.add(t4);
        set.add(t5);
        set.add(t6);

        System.out.println(set.size()); //
        System.out.println(set);
    }
}
package com.cskaoyan.set;

public class Teacher implements Comparable<Teacher> {
    private String name;
    private int age;

    public Teacher() {
    }

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

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    @Override
    public int compareTo(Teacher t) {
        // 先按年龄比较,再按姓名比较
        int cmp = age - t.age;
        cmp = cmp != 0 ? cmp : name.compareTo(t.name);
        return cmp;
    }
}

3.LinkedHashSet

可以存储null

从双向链表那体现顺序

/*
LinkedHashSet:
    HashSet 的子类
    底层是HashMap & 双向链表
    HashMap 保证了元素的唯一性。
    链表定义了迭代的顺序,按照元素的插入顺序进行迭代。
    不同步。

注意事项:
    它依赖于存储元素的两个方法: int hashCode() & boolean equals(Object obj)
    千万不要修改 HashSet 元素的属性值!
 */
public class LinkedHashSetDemo1 {
    public static void main(String[] args) {
        LinkedHashSet<String> set = new LinkedHashSet<>();
        set.add("catalina");
        set.add("diana");
        set.add("allen");
        set.add("beyonce");
        set.add("allen");
        set.add("allen");
        set.add(null);
        set.add(null);
        set.add(null);
        System.out.println(set);
    }
}

 

练习:将成绩存入IO文件

package com.cskaoyan.exercise;

public class Student {
    private String name;
    private int chinese;
    private int math;
    private int english;

    public Student() {
    }

    public Student(String name, int chinese, int math, int english) {
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
    }

    public String getName() {
        return name;
    }

    public int getChinese() {
        return chinese;
    }

    public int getMath() {
        return math;
    }

    public int getEnglish() {
        return english;
    }

    public int totalScore() {
        return chinese + math + english;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", chinese=" + chinese +
                ", math=" + math +
                ", english=" + english +
                '}';
    }
}
package com.cskaoyan.exercise;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Comparator;
import java.util.TreeSet;

/*
录入4个学生信息 (姓名,语文成绩,数学成绩,英语成绩),并按照指定的格式,总分从高到低,输出到文件。
1.创建学生类
2.创建学生对象
3.添加到TreeSet中,按照总分从高到低进行排序
4.把TreeSet中的学生信息输出到文件
 */
public class Ex1 {
    public static void main(String[] args) {
        Student s1 = new Student("刘亦菲", 100, 100, 100);
        Student s2 = new Student("迪丽热巴", 90, 90, 90);
        Student s3 = new Student("古力娜扎", 90, 90, 90);
        Student s4 = new Student("佟丽娅", 95, 95, 95);

        TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int cmp = s2.totalScore() - s1.totalScore();
                cmp = cmp != 0 ? cmp : s2.getChinese() - s1.getChinese();
                cmp = cmp != 0 ? cmp : s2.getMath() - s1.getMath();
                // cmp = cmp != 0 ? cmp : s2.getEnglish() - s1.getEnglish();
                cmp = cmp != 0 ? cmp : s2.getName().compareTo(s1.getName());
                return cmp;
            }
        });

        set.add(s1);
        set.add(s2);
        set.add(s3);
        set.add(s4);
        System.out.println(set.size());
        System.out.println(set);

        // 把TreeSet中的学生信息输出到文件
        try (PrintWriter out = new PrintWriter(new FileWriter("student.txt"))) {
            out.println("姓名\t语文\t数学\t英语\t总分");
            for(Student s : set) {
                out.println(s.getName() + "\t" + s.getChinese() + "\t" + s.getMath() +
                        "\t" + s.getEnglish() + "\t" + s.totalScore());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值