JAVA学习之集合

集合

什么是算法和数据结构
1.算法
【1】可以解决具体问题 eg: 1+2+3+4+。。。+100 --> 5050
解题流程 = 算法
【2】有设计解决的具体流程
算法1:1+2=3 , 3+3=6 .。。。 加到100 --> 5050
算法2:(1+100)*50/2 = 5050
【3】有评价这个算法的具体指标 --> 时间复杂度 空间复杂度 (从数学角度考虑)

2.数据结构:就是在计算机的缓存,内存,硬盘,如何组织管理数据的。
重点在结构上,按照什么结构来组织管理我们的数据
数据结构分为:
【1】逻辑结构: --> 思想上的结构 --> 线性表(数组,链表) , 图, 树,栈,队列
【2】物理结构: --> 真实的结构 --> 紧密结构(顺序结构) ,跳转结构(链式结构)

物理结构: 紧密结构(顺序结构) ,跳转结构(链式结构)
以线性表为例
在这里插入图片描述
线性表的特点:
n个类型相同的数据元素的有限序列
【1】相同数据类型
【2】序列(顺序性)
【3】有限

逻辑结构和物理结构的关系
线性表逻辑结构,对应的真实结构如果是紧密结构 --> 典型:数组
在这里插入图片描述

线性表逻辑结构,对应的真实结构如果是跳转结构 --> 典型:链表
优点:添加,删除 元素 效率高
缺点:查询元素效率低
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

集合引入

【1】数组,集合 都是对多个数据进行存储操作的,简称为容器
ps: 这里的存储指的是内存层面的存储。而不是持久化存储
【2】数组特点:
1.数组一旦指定了长度,那么长度就被确定了,不可以更改
int[] arr = new int[6]
2.数组一旦声明了类型以后,数组中只能存放这个类型的数据。数组中只能存放同一种类型的数据
【3】数组的缺点:
1.数组一旦确定长度,不可修改
2.删除元素,或增加元素,效率低
3.数组中实际元素的数量是没有办法获取的,没有提供对应的方法或属性来获取
4.数组存储:有序,可重复,对于无序的,不可重复的,数组不能满足要求
【4】正因为上面的缺点,引入了一个新的存储数据的结构 --> 集合

简要集合结构图

在这里插入图片描述

Collection接口的常用方法

public class Test01 {

    public static void main(String[] args) {
        /**
         * Collection接口的方法
         * 1.增加: add(E e) addAll()
         * 2.删除: clear()
         *        remove(Object o) removeAll(Collection<?> c)
         *        retainAll(Collection<?> c)
         * 3.修改:
         * 4.查询: iterator()
         *        size()
         *        toArray()
         *        toArray(T[] a)
         *  5.判断: equals(Object o) isEmpty()
         *         contains(Object o) containsAll(Collection<?> c)
         */
        Collection col = new ArrayList();
        col.add("aaa");
        col.add(1);
        col.add(true);
        col.add(9.9);
        col.add('a');

        List<Integer> intList = Arrays.asList(new Integer[]{11, 15, 14, 41});

        // addAll
        col.addAll(intList);
        // clear() 清空集合
        col.clear();
        // size()
        col.size();
        // isEmpty
        col.isEmpty();
        // remove()
        boolean isRemove = col.remove(1);
        // equals
        List<Integer> intList1 = Arrays.asList(new Integer[]{1, 2, 3});
        List<Integer> intList2 = Arrays.asList(new Integer[]{1, 2, 3});
        boolean equals = intList1.equals(intList2);
        // containsAll(Collection<?> c) contains(Object o)
        List<Integer> intList3 = Arrays.asList(new Integer[]{1, 2, 3, 4});
        List<Integer> intList4 = Arrays.asList(new Integer[]{1, 2, 3});
        boolean contains = intList3.containsAll(intList4);
        System.out.println(contains);
    }
}

集合遍历

public class Test02 {
    public static void main(String[] args) {
        Collection<Integer> col = Arrays.asList(new Integer[]{1, 2, 3, 4, 5, 6});

        // 对集合进行遍历
        // 方式1.普通for循环 无法遍历
        /*for (int i = 0; i < col.size(); i++) {
            col.
        }*/
        // 方式2. 增强for循环
        for (Integer integer : col) {
            System.out.println(integer);
        }
        // 方式3. iterator()
        Iterator<Integer> iterator = col.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

在这里插入图片描述

List接口的常用方法

public class Test03 {
    public static void main(String[] args) {
        /**
         * List接口常用方法
         * 1.增加: add(int index , E element)
         *
         * 2.删除: remove(int index)
         *        remove(Object o)
         * 3.修改: set(int index, E element)
         * 4.查询: get(int index)
         *  5.判断:
         */
        List list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(3,1);

        //set(int index, E element) 修改指定索引位置的元素
        list.set(3,2);

        // remove(int index)
        // 在集合中存入的是Integer类型数据的时候,调用remove()方法调用的是:remove(int index)
        list.remove(3);

        // remove(Object o)
        list.add("abc");
        list.remove("abc");
        
        // get(int index) 通过索引查看元素
        Object o = list.get(0);
        
        // List集合遍历
        // 方式一:普通for循环
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        // 方式二:增强for循环
        for (Object o1 : list) {
            System.out.println(o1);
        }
        // 方式三:iterator
        Iterator it = list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

ArrayList源码

jdk1.7
【1】底层源码重要属性
在这里插入图片描述
在jdk1.7中:在调用构造器的时候给底层数组elementData初始化,数组初始化长度为10
在这里插入图片描述
内存:
在这里插入图片描述
调用add方法
在这里插入图片描述
当数组中的10个位置都满了的时候就开始进行扩容,扩容长度为原数组的1.5倍
在这里插入图片描述
在这里插入图片描述
jdk1.8ArrayList底层源码
【1】jdk1.8底层依旧是Object类型数组,size:数组中的有效长度
在这里插入图片描述
【2】ArrayList al = new ArrayList();调用空构造器
在这里插入图片描述
【3】add方法

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Vector

【1】底层Object数组,int类型属性表示数组中的有效长度

【2】Vector v= new Vector(); 调用构造器
在这里插入图片描述
【3】 add方法
在这里插入图片描述

在这里插入图片描述

LinkedList源码

底层为链表(双向链表)

package com.jf.test02;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        /*
        LinkedList常用方法
        增加: addFirst(E e) addLast(E e)
             offer(E e) offerFirst(E e) offerLast(E e)
        删除: poll()
             pollFirst() pollLast() // jdk1.6之后新出的方法,提高了代码的健壮性
             removeFirst() removeLast()
        修改:
        查看: element() getFirst() getLast() indexOf(Object 0) lastIndexOf(Object o)
                peek() peekFirst() peekLast()
        判断:
         */

        LinkedList<String> list = new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("a");
        list.add("b");
        list.add("c");
        System.out.println(list); // linkedList可以添加重复数据
        list.addFirst("d");
        list.addLast("d");
        System.out.println(list);
        list.offer("ee");
        list.offerFirst("haha");
        list.offerLast("ff");
        System.out.println(list);

        System.out.println(list.poll()); // 删除头部元素 并返回对应元素
        System.out.println(list.pollFirst());
        System.out.println(list.pollLast()); // 删除尾部元素 并返回对应元素
        System.out.println(list);

        //list.clear();
        System.out.println(list);
        //System.out.println(list.pollFirst());
        //System.out.println(list.removeFirst()); // 报错 Exception in thread "main" java.util.NoSuchElementException
        System.out.println(list.poll());


        //集合的遍历
        System.out.println("-------------------------------------------------");
        // 普通for循环
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        System.out.println("-------------------------------------------------");
        // 增强for循环
        for (String s : list) {
            System.out.println(s);
        }

        System.out.println("-------------------------------------------------");
        // 迭代器
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
        }

        // 迭代器另一种写法,节省内存

        for(Iterator<String> iterator1 = list.iterator();iterator1.hasNext();){
            System.out.println(iterator1.next());
        }
    }
}

模拟LinkedList底层代码

抽象节点 Node

public class Node {
    /**
     * 节点类
     * 三个属性
     * 1.上一个元素的地址
     * 2.当前存入的元素
     * 3.下一个元素的地址
     */

    // 上一个元素的地址
    private Node pre;
    // 当前存入的元素
    private Object obj;
    // 下一个元素的地址
    private Node next;

    @Override
    public String toString() {
        return "Node{" +
                "pre=" + pre +
                ", obj=" + obj +
                ", next=" + next +
                '}';
    }

    public Node getPre() {
        return pre;
    }

    public void setPre(Node pre) {
        this.pre = pre;
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

抽象链表 MyLinkedList

public class MyLinkedList {
    /**
     * 链中一定有一个首节点
     * 链中一定有一个尾节点
     * 计数器; 每添加一个元素+1
     * 提供一个构造器
     * 添加元素方法
     */

    // 当前链中的首节点
    Node first;

    // 当前链中的尾节点
    Node last;

    // 当前链中的元素个数
    int count = 0;

    public MyLinkedList() {
    }

    public void add(Object o ){
        if(first == null){ // 证明添加的元素是第一个节点
            Node n = new Node(); // 将添加的元素封装为一个Node对象
            n.setPre(null);
            n.setObj(o);
            n.setNext(null);

            first = n;
            last = n;
        }else{
            Node n = new Node(); // 证明链表中已经存在元素
            n.setPre(last); // 节点n的上一个节点一定是当前链中的最后一个节点last.
            n.setObj(o);
            n.setNext(null);// 节点n的下一个节点为null  当前添加的节点就是最新的节点,后面在没有元素

            last.setNext(n); // 当前链中的最后一个节点的下一个元素要指向n

            last = n; // 当前链中的最后一个节点要变为最新的节点n

        }
        count++;
    }

    public int getSize(){
        return count;
    }

    public Object getElement(int index){
        // 获取链表的头元素
        Node n = first;
        for (int i = 0; i < index; i++) {
            n = n.getNext();
        }
        return n.getObj();
    }

    public String toString(){
        Node n = first;
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("[");
        stringBuffer.append(n.getObj());
        stringBuffer.append(",");
        for (int i = 0; i < count -1; i++) {
            Node next = n.getNext();
            stringBuffer.append(next.getObj());
            stringBuffer.append(",");
            n = next;
        }
        stringBuffer.append("]");
        return stringBuffer.toString();
    }

    @Test
    public void test1(){
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.add("aa");
        myLinkedList.add("bb");
        myLinkedList.add("cc");
        System.out.println(myLinkedList.getSize());
        System.out.println(myLinkedList.getElement(1));
        System.out.println(myLinkedList.toString());
    }

}

迭代器

【1】Iterable接口 与 iterator方法 与 Iterator接口的关系
在这里插入图片描述
【2】hasNext() , next()具体实现
在这里插入图片描述
【3】增强for循环,也是通过迭代器实现的

ListIterator

public class Test05 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        list.add("ee");

        // 在“cc”之后添加一个字符串“kk”
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            if("cc".equals(iterator.next())){
                list.add("ff");
            }
        }
    }
}

并发修改异常: 迭代的同时对集合进行添加操作 引发异常
在这里插入图片描述
引入新迭代器: ListIterator

public class Test05 {                                  
    public static void main(String[] args) {           
        ArrayList<String> list = new ArrayList<>();    
        list.add("aa");                                
        list.add("bb");                                
        list.add("cc");                                
        list.add("dd");                                
        list.add("ee");                                
                                                       
        // 在“cc”之后添加一个字符串“kk”                          
        /*Iterator<String> iterator = list.iterator(); 
        while(iterator.hasNext()){                     
            if("cc".equals(iterator.next())){          
                list.add("ff");                        
            }                                          
        }*/                                            
        ListIterator<String> it = list.listIterator(); 
        while(it.hasNext()){                           
            if("cc".equals(it.next())){                
                it.add("ff");                          
            }                                          
        }                                              
        System.out.println(list);                      
    }                                                  
}                                                      

Set接口

HashSet实现类

【1】普通的引用数据类型

public class Test06 {
    public static void main(String[] args) {
        HashSet<Integer> hashSet = new HashSet<>();
        hashSet.add(19);
        hashSet.add(5);
        hashSet.add(19);
        hashSet.add(20);
        hashSet.add(41);
        hashSet.add(0);
        int size = hashSet.size(); // 唯一 无序
        System.out.println(size); // 5
        System.out.println(hashSet); // [0, 19, 20, 5, 41]
    }
}

【2】自定义引用数据类型
ps: 并不满足唯一,无序特点

public class TestStudent {
    public static void main(String[] args) {
        HashSet<Student> hashSet = new HashSet<>();
        hashSet.add(new Student(19,"lili"));
        hashSet.add(new Student(20,"lulu"));
        hashSet.add(new Student(18,"feifei"));
        hashSet.add(new Student(19,"lili"));
        hashSet.add(new Student(10,"nana"));
        System.out.println(hashSet.size()); // 5
        System.out.println(hashSet);
        // 并不满足唯一无序特点
        // [Student{age=18, name='feifei'}, Student{age=10, name='nana'}, Student{age=20, name='lulu'}, Student{age=19, name='lili'}, Student{age=19, name='lili'}]
    }
}

【3】HashSet原理图:(简要原理图)
在这里插入图片描述

LinkedHashSet实现类

LinkedHashSet,就是在HashSet的基础上,多了一个总的链表,这个总链表将放入的元素串在一起,方便有序的遍历

public class TestStudent {
    public static void main(String[] args) {
        LinkedHashSet<Student> hashSet = new LinkedHashSet<>();
        hashSet.add(new Student(19,"lili"));
        hashSet.add(new Student(20,"lulu"));
        hashSet.add(new Student(18,"feifei"));
        hashSet.add(new Student(19,"lili"));
        hashSet.add(new Student(10,"nana"));
        System.out.println(hashSet.size());
        System.out.println(hashSet);
    }
}

比较器的使用

【1】以int类型为案例
比较思路:将比较的数据做差,然后返回一个int类型的数据,将这个int类型的数据按照 =0 >0 <0 进行比较

	int a = 10;
	int b = 20;
	System.out.println(a-b);

【2】比较String类型的数据:
String类实现了Comparable接口,这个接口中有一个抽象方法compareTo,String类中重写这个方法即可

    String str1 = "A";
    String str2 = "B";
    int i = str1.compareTo(str2);
    System.out.println(i);

【3】比较自定义数据类型
1.内部比较器

public class Student implements Comparable<Student> {
    private int age;
    private double height;
    private String name;

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

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

    public int getAge() {
        return age;
    }

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

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public int compareTo(Student o) {
        // 按照年龄进行比较
        //return this.getAge() - o.getAge();
        // 比较身高
        return ((Double)this.getHeight()).compareTo((Double)o.getHeight());
    }
}
public class Test01 {
    public static void main(String[] args) {
        Student s1 = new Student(10, 160, "lili");
        Student s2 = new Student(14, 170.5, "nana");
        int res = s1.compareTo(s2);
        System.out.println(res);
    }
}

2.外部比较器

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

    public Student() {
    }

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

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

    public int getAge() {
        return age;
    }

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

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

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

class BiJiao01 implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        // 比较年龄
        return o1.getAge() - o2.getAge();
    }
}

class BiJiao02 implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        // 比较名字
        return o1.getName().compareTo(o2.getName());
    }
}

class BiJiao03 implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        if(o1.getAge() == o2.getAge()){
            return o1.getName().compareTo(o2.getName());
        }else{
            return o1.getAge() - o2.getAge();
        }
    }
}
public class Test01 {
    public static void main(String[] args) {
        Student s1 = new Student(20,160.5,"nannan");
        Student s2 = new Student(21,170.5,"shuaishuai");

        // 比较身高
        Comparator comparator = new BiJiao01();
        comparator.compare(s1,s2);
        // 比较姓名  多态的应用
        Comparator comparator1 = new BiJiao02();
        comparator1.compare(s1,s2);
    }
}

【4】外部比较器与内部比较器的比较
外部比较器比内部比较器好,运用到多态,扩展性好

TreeSet实现类的使用

【1】存入Integer类型的数据 (底层使用内部比较器)

public class Test01 {
    public static void main(String[] args) {
        TreeSet<Integer> ts = new TreeSet<>();
        ts.add(12);
        ts.add(3);
        ts.add(7);
        ts.add(9);
        ts.add(3);
        ts.add(16);
        int size = ts.size();
        System.out.println(size);
        System.out.println(ts);
    }
}

特点:唯一,无序(没有按照输入顺序进行输出),有序(按照升序进行遍历)
【2】原理:底层:二叉树(数据结构中的一种逻辑结构)
在这里插入图片描述
【4】放入自定义Student类型的数据

public class Student implements Comparable<Student>{

    private int age;
    private int height;
    private String name;

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

    public Student() {
    }

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

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

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

    public int getAge() {
        return age;
    }

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

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public int compareTo(Student o) {
        return this.getAge() - o.getAge();
    }
}

利用内部比较器

public class Test03 {
    public static void main(String[] args) {
        // 利用内部比较器
        TreeSet<Student> treeSet = new TreeSet<>();
        treeSet.add(new Student(10,190,"elili"));
        treeSet.add(new Student(10,190,"flili"));
        treeSet.add(new Student(8,160,"blili"));
        treeSet.add(new Student(12,150,"alili"));
        System.out.println(treeSet);
        //[Student{age=8, height=160, name='blili'}, Student{age=10, height=190, name='elili'}, Student{age=12, height=150, name='alili'}]
    }
}

利用外部比较器

public class Test04 {
    public static void main(String[] args) {
        Comparator<Student> comparator = new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        };
        TreeSet<Student> treeSet = new TreeSet<>(comparator);
        treeSet.add(new Student(10,190,"elili"));
        treeSet.add(new Student(10,190,"flili"));
        treeSet.add(new Student(8,160,"blili"));
        treeSet.add(new Student(12,150,"alili"));
        System.out.println(treeSet);
    }
}
public class Test04 {
    public static void main(String[] args) {

        TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        treeSet.add(new Student(10,190,"elili"));
        treeSet.add(new Student(10,190,"flili"));
        treeSet.add(new Student(8,160,"blili"));
        treeSet.add(new Student(12,150,"alili"));
        System.out.println(treeSet);
    }
}

【4】TreeSet底层的二叉树的遍历时按照升序的结果出现的这个升序是靠中序遍历得到的
在这里插入图片描述

集合总览

在这里插入图片描述

Map接口

public class Test01 {
    public static void main(String[] args) {
        /**
         * 增加:put(K key , V value)
         * 删除:clear() remove(Object key)
         * 修改:
         * 查看:entrySet() get(Object key)
         *      keySet() size() values()
         * 判断:containsKey(Object key) containsValue(Object value)
         *      equals(Object o) isEmpty()
         */
        Map<String,Integer> map = new HashMap();
        map.put("lili",12);
        map.put("Alice",13);
        map.put("feifei",15);
        map.put("lili",13);
        int size = map.size();
        System.out.println(size);
        System.out.println(map);

        //map.clear(); 清空

        map.remove("lili"); // 移除

        map.containsKey("lili"); // 是或否包含指定的key

        map.containsValue(15); // 是否包含指定的Value

        map.isEmpty(); // 判断集合是否为空

        Integer alice = map.get("Alice"); // 返回指定key对应的value

        System.out.println("-------------------------------");

        Set<String> strs = map.keySet(); // 获取集合中的全部key
        for (String str : strs) {
            System.out.println(str);
        }

        Collection<Integer> values = map.values(); // 获取集合中的全部value值
        for (Integer value : values) {
            System.out.println(value);
        }

        System.out.println("-------------------------------");

        Set<String> set = map.keySet(); // 获取集合中全部的key值
        for (String s : set) {
            System.out.println(map.get(s));
        }

        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            entry.getKey();
            entry.getValue();
        }
    }
}

TreeMap实现类

【1】key的类型为String类型

public class Test02 {
    public static void main(String[] args) {
        Map<String,Integer> map = new TreeMap<>();
        map.put("blili",1234);
        map.put("alili",2345);
        map.put("blili",5487);
        map.put("clili",5698);
        map.put("dlili",2343);
        int size = map.size();
        System.out.println(size);
        System.out.println(map);// {alili=2345, blili=5487, clili=5698, dlili=2343}
    }
}

【2】key的类型为自定义类型.
内部比较器

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

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

    @Override
    public int compareTo(Student o) {
        return this.getAge() - o.getAge();
    }

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




    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }
}
public class Test03 {
    public static void main(String[] args) {
        Map<Student,Integer> map = new TreeMap<>();
        map.put(new Student(19,"blili",170),1001);
        map.put(new Student(18,"blili",150),1003);
        map.put(new Student(19,"alili",180),1023);
        map.put(new Student(17,"clili",170),1001);
        map.put(new Student(10,"dlili",140),1546);
        map.put(new Student(19,"blili",130),1254);
        System.out.println(map);
        System.out.println(map.size());
    }
}

外部比较器

public class Test03 {
    public static void main(String[] args) {
        Comparator<Student> com = new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        }
        Map<Student,Integer> map = new TreeMap<>(com);
        map.put(new Student(19,"blili",170),1001);
        map.put(new Student(18,"blili",150),1003);
        map.put(new Student(19,"alili",180),1023);
        map.put(new Student(17,"clili",170),1001);
        map.put(new Student(10,"dlili",140),1546);
        map.put(new Student(19,"blili",130),1254);
        System.out.println(map);
        System.out.println(map.size());
    }
}

HashMap 底层源码

 

TreeMap底层源码

public class TreeMap<K,V>{
	// 重要属性
	// 外部比较器
	private final Comparator<? super K> comparator;
	// 树的根节点
    private transient Entry<K,V> root = null;
	// 集合中元素的数量
	private transient int size = 0;
	// 空构造器:
	public TreeMap() {
		// 如果使用空构造器,底层就不使用外部构造器
        comparator = null;
    }
	// 有参构造器
	public TreeMap(Comparator<? super K> comparator) {
		// 如果使用有参构造器,相当于指定了外部构造器
        this.comparator = comparator;
    }
	
	public V put(K key, V value) {// K V 在创建对象时,就以确认
        // 如果放入的是第一对元素,那么t的值是null
		Entry<K,V> t = root;// 在放入第二个节点的时候,root已经是根节点了
        if (t == null) {// 如果放入第一对元素,会执行这里
            compare(key, key); // type (and possibly null) check
			// 根节点确认为root节点  key  value  parent
            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
		// 将外部比较器赋给cpr
        Comparator<? super K> cpr = comparator;
		// cpr不为null  意味着使用了有参构造器,指定了外部比较器
        if (cpr != null) {
            do {
                parent = t;
				// 将元素的key值做比较
                cmp = cpr.compare(key, t.key);
				// cpr返回的就是一个int类型的值
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else// cmp == 0
                    return t.setValue(value);
            } while (t != null);
        }
        else { // 没有使用外部比较器, 使用内部比较器
            if (key == null)
                throw new NullPointerException();
            Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }


}

在这里插入图片描述

TreeSet底层源码

public class TreeSet<E> extends AbstractSet<E>{
	// 重要属性
	private transient NavigableMap<E,Object> m;
	
	private static final Object PRESENT = new Object();

	// 在调用空构造器的时候,底层创建了一个TreeMap
	public TreeSet() {
        this(new TreeMap<E,Object>());
    }
	
	// TreeMap implements NavigableMap
	TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }

	public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }

}

Collections工具类

public class Test06 {
    public static void main(String[] args) {
        //Collections不支持创建对象,构造器私有化
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        Collections.addAll(list,"dd","ee");
        Collections.addAll(list,new String[]{"gg","pp"});

        // sort
        Collections.sort(list);

        // binarySearch
        int ccIndex = Collections.binarySearch(list, "cc");
        System.out.println(ccIndex);

        // copy  将arr2上的内容替换到list上
        ArrayList<String> arr2 = new ArrayList<>();
        Collections.addAll(arr2,"tt","ss");
        Collections.copy(list,arr2);

        // fill 填充
        Collections.fill(arr2,"yy");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值