TreeSet+TreeMap+Collections工具类

奋斗吧
奋斗吧
擅长邻域:未填写

标签: TreeSet+TreeMap+Collections工具类 Java博客 51CTO博客

2023-05-17 18:24:09 202浏览

TreeSet+TreeMap+Collections工具类,1. TreeSet特点举例说明排序: TreeSet代码在com.stulzl.treeset_.包中TreeSet_packagecom.stulzl.treeset_;importjava.util.Comparator;importjava.util.TreeSet;//TreeSet特点举例说明543@SuppressWarnings({"all

1. TreeSet特点举例说明

排序: TreeSet

代码在com.stulzl.treeset_.包中

TreeSet_

package com.stulzl.treeset_;

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

//TreeSet特点举例说明  543
@SuppressWarnings({"all"})
public class TreeSet_ {
    public static void main(String[] args) {

        //解读
        //1. 当我们使用无参构造器,创建 TreeSet 时,仍然是无序的
        //2. 希望添加的元素,按照字符串大小来排序
        //3. 使用 TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)
        // 并指定排序规则
        //4. 简单看看源码
        //解读
        /*
        1. 构造器把传入的比较器对象,赋给了 TreeSet 的底层的 TreeMap 的属性 this.comparator
        public TreeMap(Comparator comparator) {
            this.comparator = comparator;
        }
        2. 在 调用 treeSet.add("tom"), 在底层会执行到
        if (cpr != null) {//cpr 就是我们的匿名内部类(对象)
            do {
                parent = t;
                //动态绑定到我们的匿名内部类(对象)compare
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else //如果相等,即返回 0,这个 Key 就没有加入(也可以理解成替换,因为数据一样嘛,老替新)
                    return t.setValue(value);
            } while (t != null);
        }
        */


        //如果要求加入的元素,按照长度大小排序
        //总结TreeSet之所以可以实现排序,就是因为用户调用有参构造器传了一个比较器compare,如果调用无参
        //构造器照样乱序
        
        //使用默认无参构造器,是无序的
        //TreeSet treeSet = new TreeSet();

        TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //将o1,o2向下转型,让后调用String的compareTo方法比较二者的字符串大小
                return ((String)o1).compareTo((String)o2);//按字符串大小比较返回
                //return ((String)o1).length()-((String)o2).length();//按长度大小比较返回
            }
        });
        //添加数据
        treeSet.add("jack");
        treeSet.add("tom");
        treeSet.add("sp");
        treeSet.add("a");
        System.out.println("treeSet="+treeSet);
        
    }
}

2. TreeMap源码解析举例  544

会排序

代码在com.stulzl.treemap_.包中

TreeMap_

package com.stulzl.treemap_;

import java.util.Comparator;
import java.util.TreeMap;

//TreeMap源码解析举例  544
@SuppressWarnings({"all"})
public class TreeMap_ {
    public static void main(String[] args) {
        //使用默认的构造器,创建 TreeMap, 是无序的(也没有排序)
        //TreeMap treeMap = new TreeMap();

        //使用可以传入比较器的有参构造器

        TreeMap treeMap = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //要求:按照传入的 k(String) 的大小进行排序
                //return ((String)o1).compareTo((String)o2);
                //按照 K(String) 的长度大小排序
                return ((String)o1).length()-((String)o2).length();
            }
        });
        treeMap.put("jack", "杰克");
        treeMap.put("tom", "汤姆");
        treeMap.put("kristina", "克瑞斯提诺");
        treeMap.put("smith", "斯密斯");

        System.out.println("treeMap="+treeMap);

        /*
            老韩解读源码:
            1. 构造器. 把传入的实现了 Comparator 接口的匿名内部类(对象),传给给 TreeMap 的 comparator
        public TreeMap(Comparator comparator) {
            this.comparator = comparator;
        }
        2. 调用 put 方法
        2.1 第一次添加, 把 k-v 封装到 Entry 对象,放入 root
        Entry t = root;
        if (t == null) {
            compare(key, key); 
            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        2.2 以后添加
        Comparator cpr = comparator;
        if (cpr != null) {
            do { //遍历所有的 key , 给当前 key 找到适当位置
                parent = t;
                cmp = cpr.compare(key, t.key);//动态绑定到我们的匿名内部类的 compare
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else //如果遍历过程中,发现准备添加 Key 和当前已有的 Key 相等,就不添加
                    return t.setValue(value);
            } while (t != null);
        }
        */
    }
}

3. Collections 工具类  545

3.1 Collections 工具类介绍

1) Collections是一个操作Set. List 和Map等集合的工具类

2) Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作

3.2 Collections操作01:(均为 static 方法)   545

1) reverse(List):反转List中元素的顺序

2) shuffle(List):对List集合元素进行随机排序

3) sort(List):根据元素的自然顺序对指定List集合元素按升序排序

4) sort(List, Comparator): 根据指定的Comparator产生的顺序对List 集合元素进行排序

5) swap(List, int, int): 将指定list集合中的i 处元素和j处元素进行交换

代码在com.stulzl.collections_01.包中

Collections_01

package com.stulzl.collections_01;

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

//Collections工具类举例说明01  545
@SuppressWarnings({"all"})
public class Collections_01 {
    public static void main(String[] args) {
        //创建一个ArrayList集合用于测试
        List list = new ArrayList();
        list.add("tom");
        list.add("smith");
        list.add("king");
        list.add("milan");
        //list.add("tom");
        System.out.println("list="+list);
        //1) reverse(List):反转List中元素的顺序
        Collections.reverse(list);
        System.out.println("list="+list);

        //2) shuffle(List):对List集合元素进行随机排序
        for (int i = 0; i <5; i++) {//使用for循环以展示每次输出的顺序都不一样
            Collections.shuffle(list);
            System.out.println("list="+list);
        }

        //3) sort(List):根据元素的自然顺序对指定List集合元素按升序排序
        Collections.sort(list);//自然顺序就是abcd……z的ascii码大小
        System.out.println("====自然排序后====");
        System.out.println("list="+list);

        //4) sort(List, Comparator): 根据指定的Comparator产生的顺序对List 集合元素进行排序
        //例如我们希望按照字符串的长度大小来排序
        System.out.println("====按照字符串的长度大小来排序====");
        Collections.sort(list, new Comparator() {//传入匿名内部类比较器
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length();
            }
        });
        System.out.println("list="+list);
        //5) swap(List, int, int): 将指定list集合中的i 处元素和j处元素进行交换
        Collections.swap(list,0,1);//即交换第一个和第二个
        System.out.println("===交换后===");
        System.out.println("list="+list);

    }
}

3.3 Collections操作02  546

1) Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素

2) Object max(Collection, Comparator): 根据Comparator指定的顺序,返回给定集合中的最大元素

3) Object min(Collection)

4) Object min(Collection, Comparator)

5) int frequency(Collection, Object): 返回指定集合中指定元素的出现次数

6) void copy(List dest,List src):将src中的内容复制到dest中

7) boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值

代码在com.stulzl.collections_02.包中

Collections_02

package com.stulzl.collections_02;

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

//Collections工具类举例说明02  546
@SuppressWarnings({"all"})
public class Collections_02 {
    public static void main(String[] args) {
        //创建一个ArrayList集合用于测试
        List list = new ArrayList();
        list.add("tom");
        list.add("smith");
        list.add("king");
        list.add("milan");
        list.add("tom");
        System.out.println("list="+list);

        //1) Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
        System.out.println("自然顺序的最大值="+ Collections.max(list));//自然顺序的最大值=tom

        //2) Object max(Collection, Comparator): 根据Comparator指定的顺序,
        //   返回给定集合中的最大元素
        //例如按长度最大
        Object maxObject = Collections.max(list, new Comparator() {//传入我们的比较器
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length();
            }
        });
        System.out.println("按长度最大="+maxObject);//按长度最大=smith

        //这俩方法和max正好相反
        //3) Object min(Collection)
        System.out.println("自然顺序的最小值="+ Collections.min(list));//自然顺序的最小值=king

        //4) Object min(Collection, Comparator)
        Object minObject = Collections.min(list, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length();
            }
        });
        System.out.println("按长度最小="+minObject);//按长度最小=tom

        //5) int frequency(Collection, Object): 返回指定集合中指定元素的出现次数
        System.out.println("tom出现的次数="+Collections.frequency(list,"tom"));//2

        //6) void copy(List dest,List src):将src中的内容复制到dest中
        //为了完成一个完整拷贝,我们需要先给 dest 赋值,大小和 list.size()一样
        ArrayList dest = new ArrayList();
        for (int i=0;i<list.size();i++){//必须保证dest和src大小一样,否则抛出异常
            dest.add("");
        }
        Collections.copy(dest,list);
        System.out.println("dest="+dest);

        //7) boolean replaceAll(List list, Object oldVal, Object newVal)
        //   :使用新值替换List对象的所有旧值
        Collections.replaceAll(list,"tom","汤姆");
        System.out.println("list="+list);

    }
}

4.练习

4.1 练习3  549

按要求完成下列任务

1)使用HashMap类实例化一 个Map类型的对象map,键(String) 和值(int) 分别用于存储员工的姓名和工资,存入数据如下:jack—— 650元; tom——1 200元; smith——2900元;

2)将jack的工资更改为2600元

3)为所有员工工资加薪100元;

4)遍历集合中所有的员工

51遍历集合由所有的工资

代码在com.stulzl.exercise03.包中

Exercise03

package com.stulzl.exercise03;

import java.util.*;

//集合练习 549
//按要求完成下列任务
//1)使用HashMap类实例化一 个Map类型的对象map,键(String) 和值(int) 分别用于存储员工的
// 姓名和工资,存入数据如下:jack—— 650元; tom——1200元; smith——2900元;
//2)将jack的工资更改为2600元
//3)为所有员工工资加薪100元;
//4)遍历集合中所有的员工
//5)遍历集合由所有的工资
@SuppressWarnings({"all"})
public class Exercise03 {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("jack",650);
        map.put("tom",1200);
        map.put("smith",2900);
        System.out.println(map);

        //2)将jack的工资更改为2600元
        map.put("tom",2600);
        System.out.println(map);
        //3)为所有员工工资加薪100元;
        //方法1 使用keySet
        Set keySet = map.keySet();//单独吧k取出来放到keySet集合中
        for (Object o :keySet) {
            //更新加100
            map.put(o,(Integer)map.get(o)+100);//(Integer)map.get(o)  Object->Integer
        }
        System.out.println(map);

//        //方法2 使用entrySet
//        Set key = map.entrySet();//将将entry类型转为Map.Entry类型
//        for (Object o :key) {
//            Map.Entry e = (Map.Entry)o;//要转为Map.Entry方便调用getKey()和getValue()方法
//        //(Integer)e.getValue()是Object类型 这个Integer转型,是为了能加100
//           map.put(e.getKey(),(Integer)e.getValue()+100);
//        }
//        System.out.println(map);

        //遍历员工
        System.out.println("=====遍历员工=====");
        Set set = map.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry next = (Map.Entry)iterator.next();//将Entry类型-->Map.Entry
            System.out.println(next.getKey());
        }
        //遍历工资
        System.out.println("=====遍历工资=====");
        //方法1
          Collection values = map.values();//将所有的v取出放在一个集合
//        Iterator iterator1 = values.iterator();
//        while (iterator1.hasNext()) {
//            Object next = iterator1.next();
//            System.out.println(next);
//        }
        //方法2
        for (Object o :values) {
            System.out.println(o);
        }

    }
}

4.2 练习4简答题  550

试分析HashSet和TreeSet分别如何实现去重的

(1) HashSet的去重机制: hashCode() + equals()底层先通过存入对象,进行运算得到一个

hash值, 通过hash值得到对应的索引,如果发现table索引所在的位置,没有数据,就直接存放如果有数据,就进行equals比较[遍历比较],如果比较后,不相同,就加入,否则就不加入,

TreeSet+TreeMap+Collections工具类_java

(2) TreeSet的去重机制:如果你传入了一个Comparator匿名对象,就使用实现的compare去

重,如果方法返回0,就认为是相同的元素/数据,就不添加,如果你没有传入一个Comparator

匿名对象,则以你添加的对象实现的Compareable接口的compareTo去重

代码在com.stulzl.exercise04.包中

Exercise04

package com.stulzl.exercise04;

import java.util.TreeSet;

//集合练习 演示TreeSet去重  550
@SuppressWarnings({"all"})
public class Exercise04 {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet();
        treeSet.add("hsp");
        treeSet.add("tom");
        treeSet.add("king");
        treeSet.add("hsp");//加入不了
        System.out.println(treeSet);
    }
}

4.3 练习3 判断输出  550

下面代码运行会不会抛出异常,并从源码层面说明原因[考察读源码+接口编程+动态绑定]

TreeSet treeSet = new TreeSet();

treeSet.add(new Person());

代码在com.stulzl.exercise05.包中

Exercise05

package com.stulzl.exercise05;


import java.util.TreeSet;

//集合练习   550
//下面代码运行会不会抛出异常,并从源码层面说明原因[考察读源码+接口编程+动态绑定]
//TreeSet treeSet = new TreeSet();
//treeSet.add(new Person();
@SuppressWarnings({"all"})
public class Exercise05 {
    public static void main(String[] args) {
        //分析源码
        //add 方法,因为 TreeSet() 构造器没有传入Comparator接口的匿名内部类
        //所以在底层调用这个 Comparable k = (Comparable) key;
        //即 把 尝试Perosn转成 Comparable类型,因为Person没有实现Comparable接口,所以转不成功
        //就会抛出ClassCastException.异常

        //TreeSet treeSet = new TreeSet();
        //treeSet.add(new Person();

        //解决后
        TreeSet treeSet = new TreeSet();
        treeSet.add(new Person("jack"));//ok
        //因为Person重写的compare比较器,只返回了0,并没有写出具体比较依据
        treeSet.add(new Person("tom"));//加不进去,
        treeSet.add(new Person("july"));//加不进去
        System.out.println();
        System.out.println(treeSet);//[Person{name='jack'}]
    }
}

//class Person{
//
//}

//解决问题  去实现Comparable接口
class Person implements Comparable{
    private String name;

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

    //比较器
    @Override
    public int compareTo(Object o) {
        return 0;
    }

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

4.4 练习6 判断输出  551

下面的代码输出什么? 

提示:这道题很有意思,稍不注意就掉进陷阱.

已知: Person类按照id和name重写了hashCode和equals方法,问下面代码输出什么?

TreeSet+TreeMap+Collections工具类_java_02

TreeSet+TreeMap+Collections工具类_java_03

代码在com.stulzl.exercise06.包中

Exercise06

package com.stulzl.exercise06;

import java.util.HashSet;
import java.util.Objects;

//集合练习 判断输出  551
//提示:这道题很有意思,稍不注意就掉进陷阱.
//已知: Person类按照id和name重写了hashCode和equals方法,问下面代码输出什么?
@SuppressWarnings({"all"})
public class Exercise06 {
    public static void main(String[] args) {
        HashSet set = new HashSet();//ok
        Person p1 = new Person(1001,"AA");//ok
        Person p2 = new Person(1002,"BB");//ok
        set.add(p1);//ok
        set.add(p2);//ok
        p1.name = "CC";
        //删除失败,因为之前修改了name为CC,p1(1001 AA)这个老位置不变,
        // 但是在计算索引时是按照这个(1001,CC)来计算的 很可能定位不到p1的老索引索引原位置
        set.remove(p1);
        System.out.println(set);//2个元素
        //这个(1001,CC)不会和p1冲突,虽然p1的那么该为CC了,但是也仅仅是修改了值老索引位置不变的
        set.add(new Person(1001,"CC"));//ok
        System.out.println(set);//3个元素
        //这个(1001,"AA"),也不会和p1冲突,因为p1修改了name为CC,他俩的值都不一样
        set.add(new Person(1001,"AA"));//ok 挂载到后面
        System.out.println(set);//4个元素
    }
}
class Person {
    public String name;
    public int id;

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id &&
                Objects.equals(name, person.name);
    }

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

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

TreeSet+TreeMap+Collections工具类_List_04

4.5 练习7  试写出Vector和ArrayList的比较?  551

试写出Vector和ArrayList的比较?

TreeSet+TreeMap+Collections工具类_List_05

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695