java基础-集合-day14

发布时间 2023-09-24 17:14:15作者: chenwen0511

1. 数据结构 算法

算法:解决问题的步骤
例如 1+2+3+...+100
50*(1+100)=5050
算法优劣的度量:时间复杂度 空间复杂度

数据结构:
计算机中如何高效的管理数据

逻辑结构:
思想层面的数据存放编排结构

物理结构:
计算机内存或者硬盘上具体的存放逻辑

以线性表这个逻辑结构来举例:两种物理结构(实现方式)

  1. 紧密结构

线性表逻辑结构,对应的真实结构如果是跳转结构---》典型就是 链表:
优点:删除元素,插入元素效率高
缺点:查询元素效率低

可以 通过第一个索引的位置计算出其他的元素索引位置

  1. 链式结构 --跳转结构
    单项链表 双向链表 循环链表 具体的可以baidu

2. 本章的重点 集合

集合:存放数据 组织数据的容器
增提分成2大阵营:一个一个存储 一对一对的存储

3. collections

    Collection接口的常用方法:
    增加:add(E e) addAll(Collection<? extends E> c)
    删除:clear() remove(Object o)
    修改:
    查看:iterator() size()
    判断:contains(Object o)  equals(Object o) isEmpty()
package com.msb.coll01;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 9:41
 * @Description: com.msb.coll01
 * @version: 1.0
 */
public class Test01 {
    public static void main(String[] args) {
        Collection col = new ArrayList();
        col.add(18);
        col.add(12);
        col.add(11);
        col.add(17);
        System.out.println(col);

        List li = Arrays.asList(new Integer[]{1, 2, 3, 4});
        col.addAll(li);
        System.out.println(col);

        //col.clear();

        System.out.println(col.size());
        System.out.println(col.isEmpty());

        boolean isRemove = col.remove(12);
        System.out.println(col);
        System.out.println(isRemove);

        Collection col1 = new ArrayList();
        col1.add(18);
        col1.add(12);
        col1.add(11);
        col1.add(17);

        Collection col2 = new ArrayList();
        col2.add(18);
        col2.add(12);
        col2.add(11);
        col2.add(17);

        System.out.println(col2.equals(col1));
        System.out.println(col2.contains(12));
    }
}

遍历:
1.普通for
2. 增强for
3. iter
迭代器的原理:

hasNext 则执行next方法
next方法:获取当前的元素 并将“指针”下移

package com.msb.coll01;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 9:48
 * @Description: com.msb.coll01
 * @version: 1.0
 */
public class Test02 {
    public static void main(String[] args) {
        Collection col = new ArrayList();
        col.add(18);
        col.add(12);
        col.add(11);
        col.add(17);
        col.add("abc");
        col.add(9.8);

        // 1.
//        for (int i = 0; i < col.size(); i++) {
//            System.out.println(col.);;
//        }

        // 2.
        for (Object o : col) {
            System.out.println(o);
        }

        //3.
        Iterator it = col.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

    }
}

4. list

List接口中常用方法:
增加:add(int index, E element)
删除:remove(int index) remove(Object o)
修改:set(int index, E element)
查看:get(int index)
判断:

package com.msb.coll01;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 9:59
 * @Description: com.msb.coll01
 * @version: 1.0
 */
public class TesList01 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(-1);
        list.add(2);
        list.add("abc");
        System.out.println(list);

        list.add(3, 66);//插入数据
        System.out.println(list);

        //list.remove(0);//index 0位置移除元素
        System.out.println(list);

        System.out.println(list.get(0));

        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        for (Object o : list) {
            System.out.println(o);
        }

        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
    }
}

ArrayList源码分析
transient Object[] elementData 存放数据
private int size; 当前有效数据的个数

容量扩容 确保能放下原色

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

初始开辟的是10个
int newCapacity = oldCapacity + (oldCapacity >> 1);
容量不够进行扩容 新的容量是原来的1.5倍数
oldCapacity >> 1 右移动一位 相当于 除以2

jdk1.8之后
elementData 的初始赋值是空的ArrayList 只有add数据之后才会第一次扩容为10

5. 泛型

【1】什么是泛型(Generic):
泛型就相当于标签
形式:<>
集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,
JDK1.5之 后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型。
Collection, List, ArrayList 这个就是类型参数,即泛型。
元素的类型设计成一个参数,这个类型参数叫做泛型。

/创建一个ArrayList集合,向这个集合中存入学生的成绩:
//加入泛型的优点:在编译时期就会对类型进行检查,不是泛型对应的类型就不可以添加入这个集合。

package com.msb.generic01;

import java.util.ArrayList;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 10:37
 * @Description: com.msb.generic01
 * @version: 1.0
 */
public class Test01 {
    public static void main(String[] args) {
        ArrayList<Integer> al = new ArrayList<>();
        al.add(98);
        al.add(92);
        al.add(78);
//        al.add("lili");
        for (Integer i : al) {
            System.out.println(i);
        }
    }
}

泛型:<>里面传递的参数 是这个对象的类型 使用的时候才会确定
注意:泛型的类型:都是引用数据类型,不能是基本数据类型

  • GenericTest 就是一个泛型类
  • <>里面就是一个参数类型,但是这个类型是什么呢?这个类型现在是不确定的,相当于一个占位
  • 但是现在确定的是这个类型一定是一个引用数据类型,而不是基本数据类型
package com.msb.generic01;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 10:41
 * @Description: com.msb.generic01
 * @version: 1.0
 */
public class GenericTest<E> {

    int age;
    String name;
    E sex;

    public void a(E n){

    }

    public void b(E[] m){

    }
}

泛型类

package com.msb.generic01;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 10:41
 * @Description: com.msb.generic01
 * @version: 1.0
 */
public class GenericTest<E> {

    int age;
    String name;
    E sex;

    public void a(E n){

    }

    public void b(E[] m){

    }
}


class Test{


    public static void main(String[] args) {
        //实例化的时候不指定泛型
        GenericTest gt1 = new GenericTest();
        gt1.a("abc");
        gt1.a(17);
        gt1.a(3.14);
        gt1.b(new String[] {"a", "b", "c"});

        //指定泛型
        GenericTest<String> gt2 = new GenericTest<>();
        gt2.sex = "男";
        gt2.a("abc");
        gt2.b(new String[]{"abc", "123"});

    }
}

泛型方法:

  • 1.什么是泛型方法:
  • 不是带泛型的方法就是泛型方法
  • 泛型方法有要求:这个方法的泛型的参数类型要和当前的类的泛型无关
  • 换个角度:
  • 泛型方法对应的那个泛型参数类型 和 当前所在的这个类 是否是泛型类,泛型是啥 无关
  • 2.泛型方法定义的时候,前面要加上
  • 原因:如果不加的话,会把T当做一种数据类型,然而代码中没有T类型那么就会报错
    
  • 3.T的类型是在调用方法的时候确定的
package com.msb.generic01;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 10:48
 * @Description: com.msb.generic01
 * @version: 1.0
 */
public class GenericTest02<E> {

    public void a(E e){}//不是泛型方法

    public static <T> void b(T t){}//是泛型方法 注意<T>的位置
}

class Demo{
    public static void main(String[] args) {
        GenericTest02<String> gt = new GenericTest02<>();
        
        gt.a("abc");
        //gt.a(123);// 不可以
        //b方法的泛型
        gt.b(19);
        gt.b("abc");
        gt.b(true);
    }
}

6. 泛型通配符

package com.msb.generic01;

import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 11:02
 * @Description: com.msb.generic01
 * @version: 1.0
 */
public class Test02 {
    public static void main(String[] args) {
        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<Integer> list3 = new ArrayList<>();

        List<?> li = null;//?泛型通配符
        li = list1;
        li = list2;
        li = list3;
    }
}

方法里面使用泛型通配符

package com.msb.generic01;

import java.util.List;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 11:04
 * @Description: com.msb.generic01
 * @version: 1.0
 */
public class Test03 {
//    public void a(List<Object> li){
//
//    }
//
//    public void a(List<String> li){
//
//    }

    public void a(List<?> li){

        for (Object o : li) {
            System.out.println(o);
        }
    }


}

使用

class T{

    public static void main(String[] args) {
        Test03 t = new Test03();
        ArrayList<Integer> arr1 = new ArrayList<Integer>();
        arr1.add(1);
        arr1.add(12);
        arr1.add(123);
        t.a(arr1);
        t.a(new ArrayList<StringList>());
        t.a(new ArrayList<ObjectList>());
    }


}

泛型受限

package com.msb.generic02;

import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 11:14
 * @Description: com.msb.generic02
 * @version: 1.0
 */
public class Test {
    public static void main(String[] args) {
        List<Object> a = new ArrayList<>();
        List<Person> b = new ArrayList<>();
        List<Student> c = new ArrayList<>();

        List<? extends Person> list1 = null;//指定 ?必须是继承Person 相当于?的上限是Person

//        list1 = a;
        list1 = b;
        list1 = c;

        List<? super Person> list2 = null;//下限是Person Person之上的才可以
        list2 = a;
        list2 = b;
//        list2 = c;

    }
}

7. linkedList

    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 o)   lastIndexOf(Object o)
         peek()
         peekFirst() peekLast()
    判断
package com.msb.linkedtest01;

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

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 11:24
 * @Description: com.msb.linkedtest01
 * @version: 1.0
 */
public class Test01 {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("fff");

        list.addFirst("ggg");
        list.addLast("hh");

        list.offer("kk");//添加元素在尾端
        list.offerFirst("pp");
        list.offerLast("rr");

        System.out.println(list);

        System.out.println(list.poll());//删除头上的元素并且将元素输出
        list.pollFirst();
        list.pollLast();

        list.removeFirst();
        list.removeLast();
        list.remove();


        System.out.println(list);

        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));

        }

        for (String s : list) {
            System.out.println(s);
        }

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

        for(Iterator<String> it1 = list.iterator();it1.hasNext();){
            System.out.println(it1.next());//节省内存
        }


    }
}

8. 模拟linkedList源码 --面试重点

package com.msb.linkedtest01;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 11:35
 * @Description: com.msb.linkedtest01
 * @version: 1.0
 */
public class MyLinkedList {
    Node first;
    Node last;
    int count;

    public MyLinkedList() {
    }

    public void add(Object o){
        if(first==null){
            Node n = new Node(null, null, o);
            first = n;
            last = n;
        }else {
            Node n = new Node(last, null, o);
            last.setNext(n);
            last = n;
        }
        count ++;

    }

    public int getSize(){
        return count;

    }

    public Object get(int index){
        Node n = first;
        for (int i = 0; i < index; i++) {
            n = n.getNext();

        }
        return n.getObj();

    }
}

class T{
    public static void main(String[] args) {
        MyLinkedList ml = new MyLinkedList();
        ml.add("aa");
        ml.add("bb");
        ml.add("cc");

        System.out.println(ml.getSize());
        System.out.println(ml.get(1));
        
    }
}

源码的实现:

package com.msb.linkedtest01;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 14:30
 * @Description: com.msb.linkedtest01
 * @version: 1.0
 */
public class JackLinkList<E> {
    transient int size = 0;
    private static class Node<E>{
        E item;
        Node<E> next;
        Node<E> prev;

        public Node(Node<E> prev, E item, Node<E> next) {
            this.item = item;
            this.next = next;
            this.prev = prev;
        }
    }

    transient Node<E> first;//链表的首节点
    transient Node<E> last;//链表的尾节点

    public JackLinkList() {
    }

    public boolean add(E e){
        linkLast(e);
        return true;
    }
    public int size(){
        return size;
    }

    //追加元素
    void linkLast(E e){
        final Node<E> l = last;
        final Node<E> newNode = new Node<E>(l, e, null);
        last = newNode;
        if(l==null){
            first = newNode;//如果是第一个被添加的元素 first指向该节点即可
        }else{
            l.next = newNode;//如果不是新节点 last的next指向新节点即可
        }
        size++;
    }
    public E get(int index){
        return node(index).item;
    }

    //通过index获取元素
    Node<E> node(int index){
        if(index<(size>>1)){
            Node<E> x = first;
            for (int i = 0; i < index; i++) {
                x = x.next;

            }
            return x;
        }else{
            Node<E> x = last;
            for (int i = size-1; i >index ; i--) {
                x = x.prev;
            }
            return x;

        }
    }
}


class T1{
    public static void main(String[] args) {
        JackLinkList<String> ml = new JackLinkList<>();
        ml.add("aa");
        ml.add("bb");
        ml.add("cc");

        System.out.println(ml.size());
        System.out.println(ml.get(1));

    }
}

这里面用到了 二分法 从前遍历 从后遍历

8. Iterrable

package com.msb.linkedtest01;

import java.util.Iterator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:00
 * @Description: com.msb.linkedtest01
 * @version: 1.0
 */
public class MyArrayList<E> {
    transient Object[] elementData;
    private int size;

    private class Itr implements Iterator<E>{
        int cursor;
        int lastRet = 1;
        @Override
        public boolean hasNext() {
            return cursor != size;//只要不相等 都返回true
        }

        @Override
        public E next() {
            int i = cursor;
            cursor = i + 1;
            Object[] elementData = MyArrayList.this.elementData;
            return (E)elementData[lastRet=i];
        }
    }
}

package com.msb.linkedtest01.com;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:08
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class msb01 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eeee");

        Iterator<String> it = list.iterator();//调用迭代方法得到迭代对象
        while (it.hasNext()){
            if("ccc".equals(it.next())){
                //System.out.println(it.next());
                list.add("ffff");
            }

        }

    }
}


一边迭代 一边 改变集合对象 则会报错

解决办法iterator方法改成 listIterator方法

package com.msb.linkedtest01.com;

import java.util.ArrayList;
import java.util.ListIterator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:08
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class msb01 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eeee");

        ListIterator<String> it = list.listIterator();//调用迭代方法得到迭代对象
        while (it.hasNext()){
            if("ccc".equals(it.next())){
                //System.out.println(it.next());
                it.add("ffff");//这里也需要换成it
            }

        }

        System.out.println(it.hasNext());
        System.out.println(it.hasPrevious());

        while (it.hasPrevious()){
            System.out.println(it.previous());
        }

        while (it.hasNext())
            System.out.println(it.next(
            ));
        System.out.println(list);
    }
}

9. HashSet

唯一 无序

package com.msb.linkedtest01.com;

import java.util.HashSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:34
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class TestSet01 {
    public static void main(String[] args) {
        HashSet<String> hs = new HashSet<>();
        hs.add("hello");
        hs.add("apple");
        hs.add("banana");
        hs.add("html");
        hs.add("apple");
        hs.add("css");
        System.out.println(hs.size());
        System.out.println(hs);
    }
}

package com.msb.linkedtest01.com;

import java.util.HashSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:35
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class TestSet02 {

    public static void main(String[] args) {
        HashSet<Integer> hs = new HashSet<>();
        System.out.println(hs.add(19));
        hs.add(5);
        hs.add(20);
        System.out.println(hs.add(19));
        hs.add(41);
        hs.add(0);
        System.out.println(hs.size());
        System.out.println(hs);
    }
}

package com.msb.linkedtest01.com;

import java.util.HashSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:39
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class TestSet03 {
    public static void main(String[] args) {
        HashSet<Person> hs = new HashSet<>();
        hs.add(new Person(19, "lili"));
        hs.add(new Person(20, "lilu"));
        hs.add(new Person(18, "feifei"));
        hs.add(new Person(19, "lili"));
        hs.add(new Person(20, "nana"));

        System.out.println(hs.size());//5
        System.out.println(hs);

    }

}

9. LinkedHashSet

package com.msb.linkedtest01.com;

import java.util.LinkedHashSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:47
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class TestSet04 {
    public static void main(String[] args) {
        LinkedHashSet<Integer> hs = new LinkedHashSet<>();
        hs.add(5);
        hs.add(20);
        System.out.println(hs.add(19));
        hs.add(51);
        hs.add(0);
        System.out.println(hs.add(19)); //false 第二次放入 19 失败

        System.out.println(hs.size());
        System.out.println(hs);//[5, 20, 19, 51, 0] 唯一 有序

    }

}

比较器 的使用
a - b > 0 --> a>b

package com.msb.linkedtest01.com;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:51
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class Test04 {
    public static void main(String[] args) {
        double d1 = 3.15;
        double d2 = 4.9;
        int bol1 = ((Double) d1).compareTo((Double) d2);// -1  d1<d2
        System.out.println(bol1);
    }
}

package com.msb.linkedtest01.com;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 15:37
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class Person implements Comparable<Person> {
    int age;
    String name;
    double height;

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

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

    @Override
    public int compareTo( Person p) {

//        // 按照年龄
//        return this.age - p.age;

//        // 按照身高
//        return ((Double)(this.height)).compareTo((Double)(p.height));
        
        // 按照名字
        return (this.name).compareTo(p.name);
    }
}

package com.msb.linkedtest01.com;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:00
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class TestCompare01 {
    public static void main(String[] args) {
        Person p1 = new Person(14, "alili", 188.0);
        Person p2 = new Person(15, "blili", 178.0);
        System.out.println(p1.compareTo(p2));
    }

}

外部比较器

package com.msb.linkedtest01.com;

import java.util.Comparator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:04
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class BiJiao01 implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        return o1.name.compareTo(o2.name);
    }
}

package com.msb.linkedtest01.com;

import java.util.Comparator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:06
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class Bijiao02 implements Comparator<Person> {

    @Override
    public int compare(Person o1, Person o2) {
        return o1.age - o2.age;
    }
}

package com.msb.linkedtest01.com;

import java.util.Comparator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:08
 * @Description: com.msb.linkedtest01.com
 * @version: 1.0
 */
public class TestComparator {
    public static void main(String[] args) {
        Person p1 = new Person(14, "alili", 188.0);
        Person p2 = new Person(15, "blili", 178.0);

        Comparator comparator1 = new BiJiao01();//名字
        System.out.println(comparator1.compare(p1, p2));

        Comparator comparator2 = new Bijiao02();// age
        System.out.println(comparator2.compare(p1, p2));
    }
}

建议使用外部比较器 多态实现不同方式的比较

10. TreeSet

package com.msb.treeset01;

import java.util.TreeSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:33
 * @Description: com.msb.treeset01
 * @version: 1.0
 */
public class Test10 {
    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);
        System.out.println(ts.size());
        System.out.println(ts);
    }
}

有序 且唯一

原理: 二叉树 --一种逻辑接口--思想 上的结构 --跳转结构

放入元素的时候:

  1. 比较 小的往左放 大的往右放 相同则不放
package com.msb.treeset01;

import java.util.TreeSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:41
 * @Description: com.msb.treeset01
 * @version: 1.0
 */
public class Test11 {
    public static void main(String[] args) {
        TreeSet<String> ts = new TreeSet<>();
        ts.add("elili");
        ts.add("blili");
        ts.add("alili");
        ts.add("elili");
        ts.add("clili");
        ts.add("flili");
        ts.add("glili");
        System.out.println(ts.size());
        System.out.println(ts);//[alili, blili, clili, elili, flili, glili]
    }
}



自定义类的比较

package com.msb.treeset01;

import java.util.TreeSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:46
 * @Description: com.msb.treeset01
 * @version: 1.0
 */
public class Test2 {
    public static void main(String[] args) {

        TreeSet<Person> ts = new TreeSet<>();
        ts.add(new Person(10, "elili"));
        ts.add(new Person(8, "blili"));
        ts.add(new Person(4, "alili"));
        ts.add(new Person(9, "elili"));
        ts.add(new Person(10, "flili"));
        ts.add(new Person(1, "dlili"));
        System.out.println(ts.size());
        System.out.println(ts);
//[Person{age=1, name='dlili'}, Person{age=4, name='alili'}, Person{age=8, name='blili'}, Person{age=9, name='elili'}, Person{age=10, name='elili'}]
    }
}

package com.msb.treeset01;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:43
 * @Description: com.msb.treeset01
 * @version: 1.0
 */
public class Person implements Comparable<Person> {
    private int age;
    private String name;

    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 Person() {
    }

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

    @Override
    public int compareTo(Person o) {
        return this.getAge() - o.getAge();//根据年龄比较
    }

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

外部比较器

package com.msb.treeset01;

import java.util.Comparator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:49
 * @Description: com.msb.treeset01
 * @version: 1.0
 */
public class MyComparator01 implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        return o1.getName().compareTo(o2.getName());
    }
}

package com.msb.treeset01;

import java.util.Comparator;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:50
 * @Description: com.msb.treeset01
 * @version: 1.0
 */
public class MyComparator02 implements Comparator<Person> {

    @Override
    public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
    }
}

package com.msb.treeset01;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:46
 * @Description: com.msb.treeset01
 * @version: 1.0
 */
public class Test12 {
    public static void main(String[] args) {

//        Comparator<Person> com1 = new MyComparator01();
        Comparator<Person> com2 = new MyComparator02();
        TreeSet<Person> ts = new TreeSet<>(com2);

        ts.add(new Person(10, "elili"));
        ts.add(new Person(8, "blili"));
        ts.add(new Person(4, "alili"));
        ts.add(new Person(9, "elili"));
        ts.add(new Person(10, "flili"));
        ts.add(new Person(1, "dlili"));
        System.out.println(ts.size());
        System.out.println(ts);
        // name 比较
        // [Person{age=4, name='alili'}, Person{age=8, name='blili'}, Person{age=1, name='dlili'}, Person{age=10, name='elili'}, Person{age=10, name='flili'}]

        // age 比较
        // [Person{age=1, name='dlili'}, Person{age=4, name='alili'}, Person{age=8, name='blili'}, Person{age=9, name='elili'}, Person{age=10, name='elili'}]
        
        
    }
}

使用匿名类

package com.msb.treeset01;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * @Auther: jack.chen
 * @Date: 2023/9/24 - 09 - 24 - 16:46
 * @Description: com.msb.treeset01
 * @version: 1.0
 */
public class Test13 {
    public static void main(String[] args) {


        TreeSet<Person> ts = new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });

        ts.add(new Person(10, "elili"));
        ts.add(new Person(8, "blili"));
        ts.add(new Person(4, "alili"));
        ts.add(new Person(9, "elili"));
        ts.add(new Person(10, "flili"));
        ts.add(new Person(1, "dlili"));
        System.out.println(ts.size());
        System.out.println(ts);
        // name 比较
        // [Person{age=4, name='alili'}, Person{age=8, name='blili'}, Person{age=1, name='dlili'}, Person{age=10, name='elili'}, Person{age=10, name='flili'}]
        
    }
}


遍历方式
左 根 右
左 12 16
3 (7和9) 12 16
3 7(9) 12 16
3 7 12 16

12 map