深造-容器

Set

Set : 无序,不可重复 无序: 存放的顺序与内部真实存储对的顺序不一致 新增内容 : static <E> Set<E> of(E... elements) 返回包含任意数量元素的不可修改集。 遍历方式: foreach iterator

public class Class001_Set {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("zhangsan");
        set.add("lisi");
        set.add("wangwu");
        set.add("wangwu");
        set.add(null);
​
        System.out.println(set);
​
        //static <E> Set<E> of(E... elements) 返回包含任意数量元素的不可修改集。
        System.out.println(Set.of(4,3,1,2,0));
​
        //foreach
        for (String str:set){
            System.out.println(str);
        }
​
        //iterator
        Iterator<String>  it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

TreeSet

底层结构:红黑树(平衡二叉树)

特点:自动对数据做默认的升序排序

应用场景:需要对数据去重,并且对数据进行排序

遍历方式:

  • foreach

  • iterate

TreeSet对不同类型的数据,不能做默认的排序

public class Class002_TreeSet {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>();
        set.add("bc");
        set.add("ac");
        set.add("abc");
        set.add("a");
        set.add("ab");
        set.add("b");
​
        System.out.println(set);
​
        TreeSet<Integer> set2 = new TreeSet<>();
        set2.add(8);
        set2.add(6);
        set2.add(3);
        set2.add(1);
​
        //E ceiling(E e) 返回此set中大于或等于给定元素的 null元素,如果没有这样的元素,则 null 。
        System.out.println(set2.ceiling(3));
​
        //E floor(E e) 返回此set中小于或等于给定元素的最大元素,如果没有这样的元素,则 null 。
        System.out.println(set2.floor(5));
​
        //E first() 返回此集合中当前的第一个(最低)元素。
        //E last() 返回此集合中当前的最后一个(最高)元素。
        System.out.println(set2.first());
​
        //E higher(E e) 返回此集合中的最小元素严格大于给定元素,如果没有这样的元素,则 null 。
        //E lower(E e) 返回此集合中的最大元素严格小于给定元素,如果没有这样的元素,则 null 。
        System.out.println(set2.lower(3));
​
        //E pollFirst() 检索并删除第一个(最低)元素,如果此组为空,则返回 null 。
        //E pollLast() 检索并删除最后一个(最高)元素,如果此集合为空,则返回 null 。
        System.out.println(set2);
        System.out.println(set2.pollFirst());
        System.out.println(set2);
    }
}

比较器:

  1. 内部比较器|自然排序:

    实现Comparable<T>接口,重写compareTo(T o)方法,方法体中制定比较规则

  2. 外部比较器|自定义排序:

    实现Comperator<T>接口,重写compare方法,方法体中制定比较规则

注意:

  1. TreeSet去重、排序都根据比较规则实现

  2. 如果指定外部比较规则,使用外部比较规则,没有指定外部比较规则,使用内部比较规则,都不在,抛出类型转换异常ClassCastException

public class Class003_Compare {
    public static void main(String[] args) {
        //默认找存储数据的内部比较规则,自然排序方式: 1)检查Goods是否实现了Comparable接口 2)通过compareTo方法实现去重与排序
        TreeSet<Goods> set = new TreeSet<>();
        set.add(new Goods(103,"水杯"));
        set.add(new Goods(101,"茶杯"));
        set.add(new Goods(102,"保温杯"));
        set.add(new Goods(102,"玻璃杯"));
        System.out.println(set);
​
        //当前TreeSet集合,存储数据使用指定的外部比较规则,实参指定的比较规则
        //TreeSet(Comparator<? super E> comparator) 构造一个新的空树集,根据指定的比较器进行排序。
        TreeSet<Goods> set2 = new TreeSet<>(new Impl());
        set2.add(new Goods(103,"水杯"));
        set2.add(new Goods(101,"茶杯"));
        set2.add(new Goods(102,"保温杯"));
        set2.add(new Goods(102,"玻璃杯"));
        System.out.println(set2);
    }
}
​
//定义一个Comparator接口实现类
class Impl implements Comparator<Goods>{
​
    /*
           o1,o2
           o1.compareTo(o2)
     返回值:
            0  ---> o1==o2
            <0 ---> o1<o2
            >0 ---> o1>02
     */
    @Override
    public int compare(Goods o1, Goods o2) {
        return o1.getId()-o2.getId();
    }
}
​
class Goods implements Comparable<Goods>{
    private int id;
    private String name;
​
    public Goods() {
    }
​
    public Goods(int id, String name) {
        this.id = id;
        this.name = name;
    }
​
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
​
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Goods goods = (Goods) o;
        return id == goods.id &&
                Objects.equals(name, goods.name);
    }
​
​
    /*
    根据商品编号做默认升序排序
            o1,o2
           o1.compareTo(o2)
     返回值:
            0  ---> o1==o2
            <0 ---> o1<o2
            >0 ---> o1>02
​
     eg :
        商品o1 : 101      '水杯'
        商品o2 : 102      '水杯'
        o1.compareTo(02) :  return 101-102--> return -1; --> {o1,o2}
        o1.compareTo(02) :  return 102-101--> return 1;  --> {o2,o1}
     */
    @Override
    public int compareTo(Goods o) {
        //this --> o1
        //o --> o2
        //return this.id-o.id;
        return o.id-this.id;
    }
}

练习:

定义员工类,使用Arrays.sort方法对多个员工做根据薪资做升序排序

public class Class004_ArraysSort {
    public static void main(String[] args) {
        Employee[] arr = {
                new Employee("胡歌",20000),
                new Employee("彭于晏",19000),
                new Employee("吴彦祖",21000),
                new Employee("刘德华",30000),
        };
​
        System.out.println(Arrays.toString(arr));
​
        //Arrays.sort() 默认升序排序
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        //static <T> void sort(T[] a, Comparator<? super T> c) 根据指定比较器引发的顺序对指定的对象数组进行排序。
        /*Arrays.sort(arr,new Comparator<Employee>(){
​
            @Override
            public int compare(Employee o1, Employee o2) {
                return Double.compare(o2.getSal(),o1.getSal());
            }
        });*/
        //lambda
        Arrays.sort(arr,(o1,o2)-> Double.compare(o2.getSal(),o1.getSal()));
​
        System.out.println(Arrays.toString(arr));
    }
}
​
class Employee implements Comparable<Employee>{
    private String username;
    private double sal;
​
    public Employee() {
    }
​
    public Employee(String username, double sal) {
        this.username = username;
        this.sal = sal;
    }
​
    public String getUsername() {
        return username;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public double getSal() {
        return sal;
    }
​
    public void setSal(double sal) {
        this.sal = sal;
    }
​
    @Override
    public String toString() {
        return "Employee{" +
                "username='" + username + '\'' +
                ", sal=" + sal +
                '}';
    }
​
    @Override
    public int hashCode() {
        return 0;
    }
​
    @Override
    public boolean equals(Object o) {
       return false;
    }
​
    @Override
    public int compareTo(Employee o) {
        return Double.compare(this.sal,o.sal);
    }
}

HashSet

  • 底层结构:哈希表(数组+链表+红黑树)

  • 特点:查询增删效率高、去重、无序

  • 应用场景:适合运用在去重、无序、查询增删效率较高的地方

  • 存储JavaBean类型数据实现去重:

    • 需要JavaBean进行重写equals与hashcode方法,需要根据对象的属性值进行判断|计算,不能根据对象地址

思考:重写hashcode与equals方法后

两个hashcode相等,equals就一定相等? 不一定

两个equals相等,hashcode就一定相等? 一定

public class Class005_HashSet {
    public static void main(String[] args) {
        System.out.println("你好".hashCode());
        System.out.println(new Employee().hashCode());
        System.out.println(new Employee().hashCode());
        System.out.println(new Integer(123).hashCode());
​
        //通过HashSet存储Javabean类型数据 : 实现正确存储,实现去重(逻辑认为: 所有成员变量值都想等就是一个对象,就应该实现去重)
        HashSet<Employee> set = new HashSet<>();
        set.add(new Employee("张正阳",20000));
        set.add(new Employee("朱宽喜",18000));
        set.add(new Employee("王家奇",19000));
        set.add(new Employee("王家奇",19000));
​
        System.out.println(new Employee("王家奇",19000).hashCode());
        System.out.println(new Employee("王家奇",19000).hashCode());
​
        System.out.println(set);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值