个人技术分享

1. TreeSet

import com.shujia.day10_Treeset_Map_Collections.other.Data;
import java.util.Comparator;
import java.util.TreeMap;
import java.util.TreeSet;

public class DemoTreeSet {
    public static void main(String[] args) {
        /*
            TODO TreeSet
                使用元素的自然顺序对元素进行排序
         */
        
        TreeSet<Integer> integers = new TreeSet<>();
        integers.add(2);
        integers.add(1);
        integers.add(3);
        integers.add(7);
        integers.add(5);

        System.out.println(integers);  // [1, 2, 3, 5, 7]

        /*
            TODO 对于字符串进行排序,是做了字典序排序
         */
        TreeSet<String> stringTreeSet = new TreeSet<>();
        stringTreeSet.add("1");
        stringTreeSet.add("3");
        stringTreeSet.add("10");
        stringTreeSet.add("4");
        stringTreeSet.add("5");
        System.out.println(stringTreeSet);  // [1, 2, 3, 4, 5] [1, 10, 3, 4, 5]

  /* TODO
        <? super String>:包括String和它的父类 
        <? extends String>:因为String是final,无法被继承,所以只包括null
         */
        // 通过comparator方法可以获取已经实现了的比较器
        //   该比较器的逻辑是由字符串提供的
        Comparator<? super String> comparator = stringTreeSet.comparator();

        System.out.println(stringTreeSet.first());
        System.out.println(stringTreeSet.last());
        // 通过给定一个左闭右开的区间 获取原先Set中的数据
        System.out.println(stringTreeSet.subSet("10", "4"));


        /*
            构造自定义类 添加到TreeSet中
         */
        TreeSet<Student> treeSet = new TreeSet<>();
        /*
       TODO 使用底层默认逻辑无法进行排序
            Exception in thread "main" java.lang.ClassCastException:
                    com.shujia.day10.Student cannot be cast to java.lang.Comparable
            public int compareTo(T o);
            解决:重写底层排序逻辑,即重写compareTo(T o)方法
         */
        treeSet.add(new Student("001","张三",18));
        treeSet.add(new Student("002","李四",19));
        treeSet.add(new Student("003","王五",20));
        treeSet.add(new Student("13","邱六",20));
        treeSet.add(new Student("012","李白",20));
        treeSet.add(new Student("4","杜甫",20));
        System.out.println(treeSet);

//        public TreeSet(Comparator<? super E> comparator) {
//            this(new TreeMap<>(comparator));
//        }

        /*
            TODO 适用于当添加的元素类不能进行修改实现Comparable接口
         */
        TreeSet<Data> datas = new TreeSet<>(new Comparator<Data>() {
            @Override
            public int compare(Data o1, Data o2) {
                return o1.getValue().compareTo(o2.getValue());
            }
        });
        datas.add(new Data("1"));
        datas.add(new Data("11"));


    }
}


// public interface Comparable<T> {
class Student implements Comparable<Student> {
    String id;
    String name;
    int age;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

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

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

    @Override
    public int compareTo(Student o) {
        // 比较两个学生的顺序 依据学生ID进行升序排序
        /*
            根据需求场景,有时字典序排序方式不太合适
            TODO 当数据中存在由00开头和没有00开头,那么需要将00忽略 如何完成
                方式1:先将数据中的左边任意个0去除 再进行排序
                方式2:在排序时,忽略0
         */
        return this.getId().compareTo(o.getId());
    }
}

2. Map接口

import java.util.ArrayList;
import java.util.HashMap;
import java.util.TreeSet;

public class DemoMap {
    
    public static void main(String[] args) {
        /*
            TODO Map
                作用: 用于存储键值对数据  K-V 类型
                注意:一个映射不能包含重复的键 K 对Map中Key只能出现一次
                     每个键最多只能映射到一个值  一个Key只能对应一个Value
                 Map接口和Collection接口的不同
                    Map是双列的,Collection是单列的 => 在其他语言中没有该限制
                           当Collection中存储的数据类型是一个键值对类 也可以实现该方法
                            使用TreeSet存储数据也可以实现相关的效果,但是比较麻烦 于是提供了Map
                    Map的键唯一,Collection的子体系Set是唯一的
                    Map集合的数据结构值针对键有效,跟值无关 而 Collection集合的数据结构是针对元素有效
         */

        // 对于TreeSet是可以进行排序的 需要给定排序规则
        TreeSet<MyHashMap.KV<Integer,String>> treeSet = new TreeSet<>();
        treeSet.add(new MyHashMap.KV(1,"one"));
        treeSet.add(new MyHashMap.KV(2,"two"));
        treeSet.add(new MyHashMap.KV(2,"2"));
        System.out.println(treeSet); //内部逻辑实现了去重效果
       
        /*
            TODO Map使用
                put 添加数据
                remove(Object key) 删除数据
                void clear()  清空数据
                boolean containsKey(Object key) 查看是否包含某个Key

         */
        HashMap<Integer, String> hashMap = new HashMap<>();
        // 添加数据
        hashMap.put(1,"one");
        hashMap.put(2,"two");
        hashMap.put(2,"2");
        System.out.println(hashMap); // {1=one, 2=2}

        String removeKeyValue = hashMap.remove(1);
        System.out.println("remove:"+removeKeyValue);
        System.out.println(hashMap); // {2=2}

        hashMap.clear();
        hashMap.put(1,"1");
        hashMap.put(2,"2");
        hashMap.put(3,"3");
        hashMap.put(4,"4");
        hashMap.put(5,"5");

        String remove = hashMap.remove(6);
        System.out.println(remove); // null

        /*
            TODO 使用自定义对象进行保存
                1.对象作为Value
         */

        HashMap<Integer, Stu> stuHashMap = new HashMap<>();
        stuHashMap.put(1,new Stu("张三",120,130,140));
        stuHashMap.put(2,new Stu("赵六",120.1,130.1,140.1));
        stuHashMap.put(3,new Stu("王五",60,70,80));
        Stu stu = stuHashMap.remove(2);
        System.out.println(stu.getTotalScore());

        Integer removeKey = 4;
        if(stuHashMap.containsKey(removeKey)){
            Stu stu4 = stuHashMap.remove(removeKey);
            System.out.println(stu4.getTotalScore()); // 防止出现 NullPointerException 空指针异常
        }


    }


}

class MyHashMap{
// 要求传入的Key必须是继承了Comparable的接口或者是实例类
   
static class KV<K extends Comparable,V> implements Comparable<KV>{
    K k;
    V v;

    public KV(K k, V v) {
        this.k = k;
        this.v = v;
    }

    /*
        TODO 由于Key要求是去重并且只能出现一次  需要拿当前对象的Key和传入的Key进行比较
            由于K是泛型,没有直接给定其类类型,所以只能调用Object方法
                 于是可以使用泛型的类型限定  要求K 是  Comparable的子实现 或者子接口,以使用其compareTo()方法
     */
    @Override
    public int compareTo(KV other) {
        return this.k.compareTo(other.k);
    }

    @Override
    public String toString() {
        return "KV{" +
                "k=" + k.toString() +
                ", v=" + v.toString() +
                '}';
    }
}

}

3.Map方法

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class DemoMap2 {
    public static void main(String[] args) {
        /*
           TODO Map方法:
                1.containsValue
                2.isEmpty
                3.size  用于计算 Map中键值对的数量
                4.get => 根据Key获取Value数据
                5.keySet => 获取所有Key
                6. 遍历
                    1.keySet
                    2.values:values()方法的作用是得到HashMap中的value的集合
                    3.entrySet
         */
        HashMap<Integer, String> integerStringHashMap = new HashMap<>();
        integerStringHashMap.put(1,"1");
        integerStringHashMap.put(2,"2");
        integerStringHashMap.put(3,"3");

        System.out.println(integerStringHashMap.containsValue("3"));

        HashMap<Integer, Stu> stuHashMap = new HashMap<>();
        stuHashMap.put(1,new Stu("张三",120,130,140));
        stuHashMap.put(2,new Stu("赵六",120.1,130.1,140.1));
        stuHashMap.put(3,new Stu("王五",60,70,80));

        System.out.println(stuHashMap.containsValue(new Stu("王五", 60, 70, 80))); // false => true
        // TODO 当对Value的对象进行判断时,是需要将所有的Value值进行遍历,并通过 equals方法判断其是否相等
        //        默认调用Object中的equals即执行对数据存储地址的比较 => 符合当下比较逻辑要对Stu进行重写方法

        System.out.println(stuHashMap.isEmpty()); // false
        System.out.println(stuHashMap.size()); // 3

        Stu stu = stuHashMap.get(2);
        System.out.println(stu);
        System.out.println(stu.getTotalScore());

        // 获取当前Key所有的数据形成Set
        Set<Integer> integers = stuHashMap.keySet();
        System.out.println(integers);
        for (Integer integer : integers) {
            System.out.println(integer);
        }

        /*
            TODO 遍历当前HashMap中的所有KeyValue数据
                key:1  value:Stu{name='张三', yw=120.0, sx=130.0, yy=140.0}
         */
        for (Integer key : stuHashMap.keySet()) {
            Stu value = stuHashMap.get(key);
            System.out.println("key:"+key+"\t"+"value:"+value);
        }

        for (Stu value : stuHashMap.values()) {
            System.out.println(value);
        }

        /*
            TODO Entry
                 Entry 表示Map中的一个元素的抽象,是一个接口  Key Value 数据
                 对于HashMap实现了Map接口,并且在内部定义了一个 Node 静态内部类 实现了 Entry 接口 表示一个元素的具体实现类
                    static class Node<K,V> implements Map.Entry<K,V> {
         */
        Set<Map.Entry<Integer, Stu>> entries = stuHashMap.entrySet();
        for (Map.Entry<Integer, Stu> entry : entries) {
            Integer key = entry.getKey();
            Stu value = entry.getValue();
            System.out.println("key:"+key+"\t"+"value:"+value);
        }

    }
}

4. TreeMap

import java.util.TreeMap;

public class DemoTreeMap {
    
    public static void main(String[] args) {
        /*
            TreeMap类概述
                键是红黑树结构,可以保证键的排序和唯一性
                作用:当存入的数据需要进行排序时,并去重时,那么此时可以使用TreeMap
         */
        TreeMap<Integer,String> treeMap = new TreeMap<>();
        treeMap.put(1,"one");
        treeMap.put(3,"three");
        treeMap.put(2,"two");
        System.out.println(treeMap);  // {1=one, 2=two, 3=three} => 对数据进行了自然排序
        System.out.println(treeMap.get(1));

        // descending 表示倒叙
        for (Integer key : treeMap.descendingKeySet()) {
            System.out.println("key:"+key+"\tvalue:"+treeMap.get(key));
        }

        //输出最后一个键值对
        System.out.println(treeMap.lastEntry());
        //输出第一个键值对
        System.out.println(treeMap.firstEntry());

        // TODO 覆盖替换Value值的方式:
        treeMap.put(2,"2");
        System.out.println(treeMap);

        // 替换数据后返回旧的值 => 对某个Key的Value值仅使用一次,使用后更新
        //replace()替换后返回替换前的值
        String oldValue = treeMap.replace(2, "22");
        System.out.println(treeMap+"\t"+oldValue);

        // 当要替换的数据需要确定是否是我们正常所设想的值时,可以使用该方法
        boolean replace = treeMap.replace(2, "2", "222");
        System.out.println(replace);
        System.out.println(treeMap);

        /*
            TODO 自定义对象作为其Key
                com.shujia.day10.TreeKey cannot be cast to java.lang.Comparable
                TreeMap 需要根据Key对数据进行排序,那么排序时,需要给定排序依据
                    底层调用是 ((Comparable<? super K>)k1).compareTo((K)k2) 需要将Key强制类型转换Comparable再调用
                        其 compareTo 方法
         */
        System.out.println("==================");
        TreeMap<TreeKey, String> stringTreeMap = new TreeMap<>();
        stringTreeMap.put(new TreeKey("1"),"1");
        stringTreeMap.put(new TreeKey("2"),"2");
        stringTreeMap.put(new TreeKey("3"),"3");
        System.out.println(stringTreeMap);


    }
}
class TreeKey implements Comparable<TreeKey>{
    String data;

    public TreeKey(String data) {
        this.data = data;
    }

    @Override
    public int compareTo(TreeKey o) {
//        System.out.println(o.data.compareTo(o.data));
        return this.data.compareTo(o.data);
    }

    @Override
    public String toString() {
        return "TreeKey{" +
                "data='" + data + '\'' +
                '}';
    }
}

5. Collections工具类

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class DemoCollections {
    
    public static void main(String[] args) {
        /*
            TODO Collections 工具类:
                public static <T> void sort(List<T> list)  排序
                public static <T> int binarySearch(List<?> list,T key) 二分查找Key对应的下标位置
                public static <T> T max(Collection<?> coll) // 最大值
                public static void reverse(List<?> list)  // 反转
                public static void shuffle(List<?> list) // 洗牌 随机对数据进行打乱顺序
         */
        ArrayList<Integer> integerArrayList = new ArrayList<>();
        integerArrayList.add(3);
        integerArrayList.add(1);
        integerArrayList.add(2);
        integerArrayList.add(4);
        Collections.sort(integerArrayList);
        System.out.println(integerArrayList);


        ArrayList<StudentObj> allStu = new ArrayList<>();
        allStu.add(new StudentObj("001","张三"));
        allStu.add(new StudentObj("003","李四"));
        allStu.add(new StudentObj("002","王五"));
        System.out.println(allStu);

        // 排序需要实现其compareTo方法
//        Collections.sort(allStu);
        Collections.sort(allStu, new Comparator<StudentObj>() {
            @Override
            public int compare(StudentObj o1, StudentObj o2) {
                return o1.id.compareTo(o2.id);
            }
        });

        StudentObj maxObj = Collections.max(allStu, new Comparator<StudentObj>() {
            @Override
            public int compare(StudentObj o1, StudentObj o2) {
                return o1.id.compareTo(o2.id);
            }
        });
        System.out.println(maxObj);

        Collections.shuffle(allStu);
        System.out.println(allStu);

    }
}

//class StudentObj implements Comparable<StudentObj>{
class StudentObj {
    String id;
    String name;

    public StudentObj(String id, String name) {
        this.id = id;
        this.name = name;
    }

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

//    @Override
//    public int compareTo(StudentObj o) {
//        return -this.id.compareTo(o.id);
//    }
}