2019-9-25【Javase】集合:set、map、queue

本文深入探讨了Java集合框架中的Set集合,包括HashSet和TreeSet的原理、应用及其区别。同时,简单介绍了队列的概念,并对Collections接口进行了讲解。此外,详细阐述了Map接口的特性,如HashMap、LinkedHashMap和TreeMap的区别,强调了它们的存储方式、排序和对null键值的支持情况。
摘要由CSDN通过智能技术生成

一、Set集合

在这里插入图片描述
Set 接口 集 : 数据是唯一存储,无序的。
HashSet实现类:
底层 数据结构 哈希表。

1.HashSet

在这里插入图片描述

数组 + 链表 + 二叉树。

原理:

在这里插入图片描述

原码:

        /*
         * new HashSet:
         * 加载因子:
         *  static final float DEFAULT_LOAD_FACTOR = 0.75f; 
         *  
         *  数组的初始容量: 16
         *   static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
         *  二叉树节点临界值:
         *  static final int TREEIFY_THRESHOLD = 8;
         *   
         */
        HashSet<String> set = new HashSet<>();
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
    }
}
        Set<String> set = new HashSet<>();
        set.add("ab");
        set.add("ac");
        set.add("ba");
        System.out.println(set);// [ab, ac, ba]
        set.add("ab");
        System.out.println(set);// [ab, ac, ba]

重写:hashCode和equals()方法:

class Student{
    private int no;
    private String name;
    public Student(int no, String name) {
        this.no = no;
        this.name = name;
    }
    public int getNo() {
        return no;
    }
    public String getName() {
        return name;
    }
    @Override
    public String toString() {
        return "Student [no=" + no + ", name=" + name + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + no;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)// guojing.equals(guojing)
            return true;
        if (obj == null)// guojing.equals(null)
            return false;
        if (this.getClass() != obj.getClass())//  guojing.equals("hello")
            return false;
        Student other = (Student) obj;// 
        if (no != other.no)
            return false;
        return true;
    }
    
/*  @Override
    public int hashCode() {
        return no;
    }
    @Override
    public boolean equals(Object obj) {
        //  只要学号相同 那么 就返回 true
        // this.no    (Student)obj .no
        Student stu = (Student)obj;// 
        return this.no == stu.no;
    }*/
    
}
public class TestHashSet1 {
​
    public static void main(String[] args) {
        Set<Student> set = new HashSet<>();
        Student guojing = new Student(11, "郭靖");
        Student yangkang = new Student(11, "郭靖");
        Student huangrong = new Student(22, "黄蓉");
        set.add(guojing);
        set.add(yangkang);
        set.add(huangrong);

    //信息
        set.forEach(System.out::println);
        
        
​
    }
​}

2、TreeSet

在这里插入图片描述

基本应用:

   public static void main(String[] args) {
        // 默认: 自然升序排序 Comparable
//      Set<String> set = new TreeSet<>();
        // Comparator
        Set<String> set = new TreeSet<>((s1,s2)->s2.compareTo(s1));
        set.add("aa");
        set.add("cc");
        set.add("bb");
//      System.out.println(set);// [aa, bb, cc]
        System.out.println(set);// [cc, bb, aa]
​
    }

底层:二叉树

树:由分支关系组成的层次结构。

在这里插入图片描述

去重:

class Employee implements Comparable<Employee>{
    private int no;
    private String name;
    private int age;
    public Employee(int no, String name, int age) {
        super();
        this.no = no;
        this.name = name;
        this.age = age;
    }
    public int getNo() {
        return no;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString() {
        return "Employee [no=" + no + ", name=" + name + ", age=" + age + "]";
    }
    @Override
    public int compareTo(Employee o) {
        //  按照年龄  升序
        int n = this.age - o.age;
        if( n == 0)
            return this.no - o.no;
        return n;
    }
    
}
public class TestTreeSet1 {
​
    public static void main(String[] args) {
        Set<Employee> set = new TreeSet<>();
        Employee guojing = new Employee(11, "郭靖", 20);
        Employee yangkang = new Employee(33, "杨康", 20);
        Employee huangrong = new Employee(22, "黄蓉", 20);
        set.add(guojing);
        set.add(yangkang);
        set.add(huangrong);
        // -----------------------------
        
   set.forEach(System.out::println);
    }
​
}

3.区别

HashSet :底层 哈希表。
hashCode() ,equals() 重写自己去重。
唯一,无序。
LinkedHashSet: 底层 链表。
唯一,有序,添加的顺序维护。
TreeSet: 底层 二叉树。
唯一,有序,默认 Comparable自然排序,自己定制顺序Comparator .

HashSet > LinkedHashSet>TreeSet
        // 无序
//      Set<String> set = new HashSet<>();
//      Set<String> set = new LinkedHashSet<>();
        Set<String> set = new TreeSet<>((s1,s2)->s2.compareTo(s1));
        set.add("aa");
        set.add("bb");
        set.add("ab");
        set.add("cc");
        
//      System.out.println(set);// [aa, bb, cc, ab] HashSEt
        //-------------顺序--------------------------------
        // 元素添加的顺序
//      System.out.println(set); // [aa, bb, ab, cc] LinkedHashSet
        // 自己定制顺序
//      System.out.println(set);// [aa, ab, bb, cc] 默认 Comparable顺序
        System.out.println(set);// [cc, bb, ab, aa] Comparator降序

二、队列

在这里插入图片描述

  public static void main(String[] args) {
        // 创建了一个队列
//      Queue<String> q = new ArrayDeque<>();
        Queue<String> q = new LinkedList<>();
        // 入队
        q.add("aa");// 添加成功true ,失败 异常
        q.add("bb");
        q.offer("cc");// 添加成功true,失败 false;
        // 要求:队列 不允许 添加null值。但是有个特殊的可以添加null值得LinkedList
        q.add(null);// java.lang.NullPointerException 
        System.out.println(q);// [aa, bb, cc]
        // 出队
//      System.out.println(q.remove());// aa 删除成功返回元素,失败异常
//      System.out.println(q.remove());// bb
//      System.out.println(q.poll());// cc 删除成功返回元素,失败 null
        // 循环出队
        while(q.size() > 0) {
            System.out.println(q.poll());
        }
        
   // 获得队头元素(获取并不删除)
//      System.out.println(q.element());// aa 获得成功 返回元素,失败异常
//      System.out.println(q.peek());// aa 获得成功返回元素,失败 null
//      System.out.println(q.size());// 0
​
    }

三、Collections

在这里插入图片描述

   public static void main(String[] args) {
        //                       LinkedList
        List<String> list = new ArrayList<>();
        // 添加
        list.add("aa");
        list.add("cc");
        // 向集合中添加多个元素
        Collections.addAll(list, "bb","dd","ee");
        System.out.println(list);// [aa, cc, bb, dd, ee]
        // 1. 排序:自然升序 Comparable  List
        Collections.sort(list);
        System.out.println(list);// [aa, bb, cc, dd, ee]
        // 2.  List
//      Collections.sort(list, (s1,s2)->s2.compareTo(s1));
//      System.out.println(list);// [ee, dd, cc, bb, aa]
        // 3. 二分查找:前提升序排序 存在 返回正数  (索引),不存在返回 -插入点-1
        System.out.println(Collections.binarySearch(list, "cc"));// 2
        // 4. 集合中最大的元素
        System.out.println(Collections.max(list));// ee
        // 5。 集合中最小的元素
        System.out.println(Collections.min(list));// aa
        // 6.  List  反转集合元素
        Collections.reverse(list);//  [ee, dd, cc, bb, aa]
        // 7. 获得 第二个参数元素 在集合中出现的次数 
        
        System.out.println(Collections.frequency(list, "aa"));// 1
        Collections.addAll(list, "aa","aa");// [ee, dd, cc, bb, aa, aa, aa]
        System.out.println(Collections.frequency(list, "aa"));// 3
        // 8. 用第二个元素 替换掉集合中的 所有元素
        Collections.fill(list, "hello");// [hello, hello, hello, hello, hello, hello, hello]
        System.out.println(list);
        
    }

四、Map

在这里插入图片描述
Map接口: 映射。 双列存储。
key/value
键/值 对
键是唯一的,值是可以重复的。

在这里插入图片描述

public static void main(String[] args) {
    // 编号/数据
    Map<Integer,String> map = new HashMap<>();
    // 添加元素
    map.put(11, "aa");
    map.put(22, "bb");
    map.put(33, "cc");
    System.out.println(map);// {33=cc, 22=bb, 11=aa}
    // 1. 键值对 的个数
    System.out.println(map.size());// 3
    // 2.
    System.out.println(map.isEmpty());// false
    // 3. 是否存在指定的键
    System.out.println(map.containsKey(11));// true
    // 4。 是否存在指定的值
    System.out.println(map.containsValue("cc"));// true
    // 5. 删除指定的键对应的键值对信息
    map.remove(33);
    System.out.println(map);// {22=bb, 11=aa}
    // 6. 获取键的集合,Set 唯一
    System.out.println(map.keySet());// [22, 11]
    // 7. 获得值得集合,Collection
    System.out.println(map.values());// [bb, aa]
    // 8. 清空集合
    map.clear();
    System.out.println(map.isEmpty());// true
    System.out.println(map.size());// 0
}

注意:

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        // 编号/数据
        Map<Integer,String> map = new HashMap<>();
//      Map<Integer,String> map = new LinkedHashMap<>();
//      Map<Integer,String> map = new TreeMap<>();
        // 添加元素
        map.put(11, "aa");
        map.put(22, "bb");
        map.put(33, "cc");
        System.out.println(map);//{33=cc, 22=bb, 11=aa}
        map.put(null, null);// HashMap,LinkedHashMap支持
//      map.put(11, "aa");// {null=null, 33=cc, 22=bb, 11=aa} 键是唯一得
        map.put(11, "hello");// {null=null, 33=cc, 22=bb, 11=hello} 键冲突,会用新得值替换旧的值
        System.out.println(map);
        
        
    }

Map得遍历:

    public static void main(String[] args) {
​
        Map<Integer,String> map = new HashMap<>();
        // 添加元素
        map.put(11, "aa");
        map.put(22, "bb");
        map.put(33, "cc");
        System.out.println(map);// {33=cc, 22=bb, 11=aa}
        // 遍历集合元素
        // 1. 集合得forEach
        map.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer t, String u) {
                System.out.println(t + "," + u);
            }
            
        });
        // Lambda
        map.forEach((k,v)->System.out.println(k + ":" + v));
        // 2. Iterator
        // 1) 分别遍历
        map.keySet().iterator().forEachRemaining(System.out::println);
        map.values().iterator().forEachRemaining(System.out::println);
        // 2) map.entrySet() 获得得是键值对Entry得集合 ,类型Set
        map.entrySet().iterator().forEachRemaining(e->{System.out.println(e.getKey()+","+e.getValue());});
        
    }

Map区别:

HashMap: 键唯一,速度快。
无序的。
支持 null键 和null值。
LinkedHashMap: 键唯一,有序,按照元素添加的顺序维护的。
支持 null键 和null值。
TreeMap: 键唯一,有序,自己定制顺序,Comparator定制顺序(键)
不支持null键 和null值。

HashMap > LinkeHashMap > TreeMap

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值