zoukankan      html  css  js  c++  java
  • 【JDK源码分析】 String.join()方法解析

    前言

    最近出于习惯问题,顺手点开了String的源码,意外发现String在JDK 8中新增了join方法。(实在惭愧,JDK 8都发布多久了。。。)

    源码

    String重载了join方法,两个方法的异同点在于,第一个方法使用的可变参数,第二个方法使用的可迭代参数,这样设计主要是为了方法适用性更广。比如参数可以传一个数组、集合等等。下面就拿一个方法的源码来解析
    String 类

         /**
         * delimiter 分隔符
         * elements 需要连接的字符数组
         */
        public static String join(CharSequence delimiter, CharSequence... elements) {
            // 空指针判断
            Objects.requireNonNull(delimiter);
            Objects.requireNonNull(elements);
    
            // Number of elements not likely worth Arrays.stream overhead.
            // 此处用到了StringJoiner(JDK 8引入的类)
            // 先构造一个以参数delimiter为分隔符的StringJoiner对象
            StringJoiner joiner = new StringJoiner(delimiter);
            for (CharSequence cs: elements) {
                // 拼接字符
                joiner.add(cs);
            }
            return joiner.toString();
        }

    查看StringJoiner源码

        // 前缀
        private final String prefix;
        // 分隔符
        private final String delimiter;
        // 后缀
        private final String suffix;
        //
        private StringBuilder value;
    
        /**
        * 构造器
        */
        public StringJoiner(CharSequence delimiter) {
            this(delimiter, "", "");
        }
    
        public StringJoiner(CharSequence delimiter,
                            CharSequence prefix,
                            CharSequence suffix) {
            Objects.requireNonNull(prefix, "The prefix must not be null");
            Objects.requireNonNull(delimiter, "The delimiter must not be null");
            Objects.requireNonNull(suffix, "The suffix must not be null");
            // make defensive copies of arguments
            this.prefix = prefix.toString();
            this.delimiter = delimiter.toString();
            this.suffix = suffix.toString();
            this.emptyValue = this.prefix + this.suffix;
        }
    
        // 拼接
        public StringJoiner add(CharSequence newElement) {
            prepareBuilder().append(newElement);
            return this;
        }
    
        // 预拼接value
        private StringBuilder prepareBuilder() {
            // value已加前缀
            if (value != null) {
                // 此时添加分隔符
                value.append(delimiter);
            } else {
                // value未加前缀时需要先添加前缀
                value = new StringBuilder().append(prefix);
            }
            return value;
        }
    
        //重写了toString 方法
        @Override
        public String toString() {
            if (value == null) {
                // value未进行任何字符拼接时反悔emptyValue
                return emptyValue;
            } else {
                // 后缀为""字符时,直接返回value
                if (suffix.equals("")) {
                    return value.toString();
                } else {
                    // 获取value未拼接后缀的长度
                    int initialLength = value.length();
                    String result = value.append(suffix).toString();
                    // reset value to pre-append initialLength
                    // 此处是为了保证value.toString()为未拼接后缀前的字符串         
                    value.setLength(initialLength);
                    return result;
                }
            }
        }   
    使用方式
            String delimiter = "-";
            String[] elements = {"JDK", "8", "String", "join"};
            List<String> list = new ArrayList<String>(Arrays.asList(elements));
    
            System.out.println(String.join(delimiter, elements));
            System.out.println(String.join(delimiter, "JDK", "8", "String", "join"));
            System.out.println(String.join(delimiter, list));

    输出结果
    输出结果

  • 相关阅读:
    Selenium WebDriver
    Xpath常用语法
    firefox插件
    Echarts图中datazoom的相关配置
    js获取当前年月日
    echarts饼图角度起始角度位置和生长方向
    jS获取table表格任意单元格值
    jquery中 cache: true和false的区别
    Ajax请求中的async:false/true的作用 、cache: true和false的区别
    Cocos Creator set get
  • 原文地址:https://www.cnblogs.com/d-homme/p/9357009.html
Copyright © 2011-2022 走看看