首页 > 编程语言 >Java-Day-19( 对集合实现类的选择 + TreeSet + TreeMap )

Java-Day-19( 对集合实现类的选择 + TreeSet + TreeMap )

时间:2023-05-11 22:45:55浏览次数:70  
标签:Java String comparator 19 TreeMap return public TreeSet

Java-Day-19

总结 - 开发中如何选择集合实现类

  • 在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行选择

    • 先判断存储的类型 ( 一组对象或一组键值对 )
  • 一组对象 ( 单列 ):Collection 接口

    • 允许重复:List

      • 增删多:LinkedList [ 底层维护了一个双向链表 ]
      • 改查多:ArrayList [ 底层维护 Object 类型的可变数组 ]
    • 不允许重复:Set

      • 无序:HashSet [ 底层是 HashMap,维护了一个哈希表 ( 数组 + 链表 + 红黑树 ) ]

      • 排序:TreeSet

      • 插入和取出顺序一致:LinkedHashSet,维护数组 + 双向链表 ( 跨索引 )

        ( LinkedHashSet 底层是 LinkedHashMap 再底层是 HashMap )

  • 一组键值对 ( 双列 ):Map

    • 键无序:HashMap [ 底层是哈希表,jdk7:数组 + 链表,jdk8:数组 + 链表 + 红黑树 ]
    • 键排序:TreeSet
    • 键插入和取出顺序一致:LinkedHashMap
    • 读取文件:Properties

TreeSet

  • 排序的话要注意构造器

    public class test1 {
        public static void main(String[] args) {
    //        无参构造器,创建仍无序
    //        TreeSet treeSet = new TreeSet();
    //        若是希望添加元素按字符串大小来排序,
    //        使用提供的一个构造器,可传入一个比较器(匿名内部类),并指定排序规则
            TreeSet treeSet = new TreeSet(new Comparator() {
                @Override
                public int compare(Object o1, Object o2) {
    //                由于举例是字符串,所以这里下转String
                    return ((String) o1).compareTo((String) o2);
                    /*
                    compareTo() 循环取出每个字符,若是不相等的就得ASCII值的差
                    o1 是新加入的值,源码可知差为负(新的小)就放左边
                     */
    
    //                从大到小的话就-更换排序规则:
    //                return ((String) o2).compareTo((String) o1);
    
    //                若是想要求加入的元素按照长度大小进行排序就:从短到长(但是存在弊端,即,同长度的就不能添加了)
    //                return ((String) o1).length() - ((String) o2).length();
                }
            });
    //        添加数据
            treeSet.add("zyz");
            treeSet.add("java");
            treeSet.add("duang");
            System.out.println(treeSet);
            /*      
            1. 构造器把传入的比较对象,赋给了TreeSet的底层的TreeMap的属性this.comparator
            public TreeMap(Comparator<? super K> comparator) {
                this.comparator = comparator;
            }
            
            TreeSet 的 add(),返回的是 TreeMap 的 put()
            value 为静态空 Object:PRESENT
            public boolean add(E e) {
            	return m.put(e, PRESENT)==null;
        	}
            可知 TreeSet 的底层就是 TreeMap
    
            2. 在调用treeSet.add第二个元素时,会在底层执行:
                Comparator<? super K> cpr = comparator;
                if (cpr != null) { // cpr:传进入的匿名内部类(对象)
                    do {
                        parent = t;
                        cmp = cpr.compare(key, t.key);
                        // 动态绑定到匿名内部类的compare方法
                        // return 的差值由cmp接收
                        if (cmp < 0)
                            t = t.left;
                        else if (cmp > 0)
                            t = t.right;
                        else // 如果相等就返回的是0,即重复无法加入
                            return t.setValue(value);
                    } while (t != null);
                }
            */
        }
    }
    

TreeMap

  • 实现 Map 接口

  • TreeSet 的底层就是 TreeMap ( 因为 TreeSet 里 add 添加的时候,进 TreeSet 的 add 方法,返回的是 TreeMap 的 put 方法 )

    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }
    
    
    public class test1 {
        public static void main(String[] args) {
    //        不使用默认的构造器(虽然默认的话也是计算ASCII码的值?)
    //        TreeMap treeMap = new TreeMap();
    //        似TreeSet,要求:匿名内部类 new Comparator
            TreeMap treeMap = new TreeMap(new Comparator() {
                @Override
                public int compare(Object o1, Object o2) {
    //                按字符 ASCII值,小到大
                    return ((String) o1).compareTo((String) o2);
                }
            });
            treeMap.put("zyz", "v-duang");
            treeMap.put("java", "v-ooo");
            treeMap.put("ooo", "v-java");
            treeMap.put("duang", "v-duang");
            System.out.println(treeMap);
    
            /*
            1. 构造器:把传入了 实现了Comparator接口的匿名内部类(对象),
            即main里编写的传到了下面一行的 comparator
            public TreeMap(Comparator<? super K> comparator) {
                this.comparator = comparator;
            }
            2. 第一次直接添加,Entry封装后存进root
                Entry<K,V> t = root;
                if (t == null) {
                    compare(key, key); // type (and possibly null) check,只是为了防止为空,空就报错
    
                    root = new Entry<>(key, value, null);
                    size = 1;
                    modCount++;
                    return null;
                }
            3. 第二次进入,把新put的进行一系列操作挂在root的left或right上(或是相同不处理):
            赋给cpr实现了的匿名内部类 Comparator<? super K> cpr = comparator;
                if (cpr != null) {
                    do { // 遍历所有的key,给当前key找到适当位置
                        parent = t; // 前面 Entry<K,V> t = root;
                        cmp = cpr.compare(key, t.key); // 动态绑定到我们匿名内部类的compare方法
                        // 下面根据compare所得决定放左还是右,
                        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;
           */
        }
    }
    

标签:Java,String,comparator,19,TreeMap,return,public,TreeSet
From: https://www.cnblogs.com/zhu-ya-zhu/p/17392459.html

相关文章

  • Java关键字总结
    finalfinal在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。final变量对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象,但是可以改变实例的属性。凡......
  • Java时间日期
    Java时间日期SimpleDateFormat格式化使用simpledateformat来自定义日期格式化运行:例1importjava.text.SimpleDateFormat;2importjava.util.Date;34publicclassTestDate{5publicstaticvoidmain(String[]args){6DatedNow=newDate();......
  • Java 编程之美总结
    内容来自王争Java编程之美1、Java基础1、程序本质:代码是如何被执行的?CPU、操作系统、虚拟机各司何职2、基础语法:从CPU角度看变量、数组、类型、运算、跳转、函数等语法3、引用类型:同样都是存储地址,为何Java引用比C/C++指针更安全4、基本类型:既然Java一切皆对......
  • Java中try...catch...finally、throw和throws的区别和联系
    在Java中经常使用的对异常的处理有:try...catch...finally、throw和throws之前使用的时候经常混淆今天花时间梳理了一下1.try...catch...finallytry中存放可能出现异常的代码,catch处理try中抛出的异常inti=0;try{System.out.println("开始......
  • javascript:void(0)
    javascript:void(0),仅仅表示一个死链接,当href=javascript:void(0)的空链接被点击时,页面不会有任何反应。让超链接去执行一个js函数,而不是去跳转到一个地址,而void(0)表示一个空的方法,也就是不执行js函数。javascript:是伪协议,表示url的内容通过javascript执行。void(0)计算结果......
  • Java 远程连接 SQLite 数据库
    Java远程连接SQLite数据库 Java可以使用JDBCAPI来连接SQLite数据库。但是,SQLite不支持远程连接,因为它是一种文件数据库,需要直接访问数据库文件。如果您需要从远程位置访问SQLite数据库,可以将SQLite数据库文件放在共享文件夹中,并将该文件夹映射到本地计算机上。......
  • HDFS文件读写初窥- Java API
    安装HDFS1)hadoop下载:https://hadoop.apache.org/releases.html2)本地安装:https://hadoop.apache.org/docs/r3.3.5/hadoop-project-dist/hadoop-common/SingleCluster.html3)修改配置:etc目录下存放了hadoop相关配置文件,这里要在本地部署伪分布式模式,需要修改以下两个文件:e......
  • 2023年5月11日19:31:14
    如果不写可能自己都忘了吧。今天我终于把三更那个个人博客做完了,前面跟着他做,后面他让我们自己做,挺好的,毕竟都是一些重复的东西,自己真 正的学到了很多很多。挺开心的。下一步就是把这个项目上线,如果能够再美化一下前端就好了,所以我还要去学一点前端,但是这个计划不知道什么时候......
  • Java面向对象
    面向对象编程(OOP)是软件开发的一种新方法,使用这种方法开发的软件具有易维护、可重用和可扩展性等特性。【特征:封装、继承、多态(抽象)】面向对象基本概念:(面向对象的设计就是一个抽象的过程)1、对象:对象就是用来描述客观事物的一个实体。用面向对象的方法解决问题,需要对现实世界中的......
  • Java8中的sort与Comparator、Comparable
    基本含义在Java8中,sort()方法、Comparator接口和Comparable接口是用于对数组或集合进行排序的重要工具,其中Comparator接口适用于自定义比较规则,而Comparable接口适用于定义对象自身的比较规则。假如我们有一个实体类点击查看代码publicclassCoinUserIncome{pr......