• 【Java基础】字符串拼接从String join 到流式处理(七夕特别版)


    1、前言

    我们经常再开发的过程中遇到一些字符串拼接的情况,我也是。

    但是最近我看了项目中的一些旧代码,就感觉很难受,

    就像过七夕,女朋友也想收到巧克力鲜花啥的,总不能一句我爱你就完了。

    生活需要仪式,代码也需要巧妙优雅。

    2、示例

    2.1、暴力拼接

    先说下坏的示例:

    String[] strs = {“a”, “b”, “c”};

    需要各个元素进行逗号拼接。

    暴力破解是怎样的?

    String resultStr = "";
    for (String str : strs) {
        resultStr = resultStr + str + ",";
    }
    System.out.println(resultStr.substring(0,resultStr.length()-1));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后IDEA就提示可以使用StringBuilder:

    StringBuilder resultStr = new StringBuilder();
    for (String str : strs) {
         resultStr.append(str).append(",");
     }
     System.out.println(resultStr.substring(0,resultStr.length()-1));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里就不说String 和 StringBuilder,StringBuffer的区别了。

    2.2、更友好的拼接 String::join

    能不能有更好的方式?

    可以,Java也是提供了很好的工具类来完成这个任务。就是JDK1.8 为 String 新增的 join 方法。

    
     public static String join(CharSequence delimiter, CharSequence... elements) {
         Objects.requireNonNull(delimiter);
         Objects.requireNonNull(elements);
         // Number of elements not likely worth Arrays.stream overhead.
         StringJoiner joiner = new StringJoiner(delimiter);
         for (CharSequence cs: elements) {
             joiner.add(cs);
         }
         return joiner.toString();
     }
     
     public static String join(CharSequence delimiter,
             Iterable<? extends CharSequence> elements) {
         Objects.requireNonNull(delimiter);
         Objects.requireNonNull(elements);
         StringJoiner joiner = new StringJoiner(delimiter);
         for (CharSequence cs: elements) {
             joiner.add(cs);
         }
         return joiner.toString();
     }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    根据方法的状态可以理解成两个方法分别可以对多个字符串集合进行拼接。

    示例:

    • 处理数组
    // String join(CharSequence delimiter, CharSequence... elements)
    String[] strs = {"a", "b", "c"};
    System.out.println(String.join(",", "a","b","c")); 
    System.out.println(String.join(",", strs));
    
    • 1
    • 2
    • 3
    • 4
    • 处理集合
    String[] strs = {"a", "b", "c"};
     // 集合
     List<String> strlist = Arrays.asList(strs);
     System.out.println(String.join(",", strlist));
    
    • 1
    • 2
    • 3
    • 4
    • 处理json
     // json
     JSONObject jsonObject = new JSONObject();
     jsonObject.put("a","aValue");
     jsonObject.put("b","bValue");
     jsonObject.put("c","cValue");
     System.out.println(String.join(",", jsonObject.keySet()));
     // idea 提示保存,无法允许
    //        System.out.println(String.join(",", jsonObject.values())); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 处理map
     Map<String,Object> map = new HashMap<>();
     map.put("ak","aMapValue");
     map.put("bk","bMapValue");
     map.put("ck","cMapValue");
     System.out.println(String.join(",", map.keySet()));
    //        System.out.println(String.join(",", map.values())); // idea 提示保存,无法允许
    
     Map<String,String> map2 = new HashMap<>();
     map2.put("ak","aMapValue");
     map2.put("bk","bMapValue");
     map2.put("ck","cMapValue");
     System.out.println(String.join(",", map2.keySet()));
     System.out.println(String.join(",", map2.values()));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    简单总结以上就是可以对字符串进行操作,集合的话也必须泛型使用字符串。map和json其实也是对其中集合的处理,json本质也是对map的实现。(这里使用fastjson)

    2.3、stream 流处理

    JDK1.8 还有一个新的语法糖的更新,其中就有数据流的处理。

    我们也可以使用stream进行处理:

    • 数组
    System.out.println(Arrays.stream(strs).collect(Collectors.joining(",")));
    
    • 1
    • 集合
    System.out.println(strlist.stream().collect(Collectors.joining(",")));
    
    • 1

    json 和 map 仍然和上诉类似。但是其实根据idea提示仍然让我们使用String.join 这是因为我们使用流的情况其实增加了内存上的开销,使解决方案更复杂了。

    那么我们什么时候需要使用呢?

    其实我们需要不仅仅是字符串拼接的情况下使用流更方便,例如:

    • Map和JSON 的values拼接
    System.out.println(jsonObject.values().stream().map(String::valueOf).collect(Collectors.joining(",")));
    
    • 1

    这里 map(String::valueOf) 就实现了Object 转换成String类型的功能。

    加以扩展我们还可以对非字符串数组进行处理。

    • 非字符串数组处理
    int[] ints = {1,2,3};
    System.out.println(Arrays.stream(ints).mapToObj(String::valueOf).collect(Collectors.joining(",")));
    
    • 1
    • 2

    这里 mapToObj(String::valueOf) 实现了基本类型 int 到 String的转换。

    • 多级map, json
     Map<String, Object> map3 = new HashMap<>();
     Map<String, Object> map4 = new HashMap<>();
     map4.put("x","x");
     map4.put("z","z");
     map3.put("y", map4);
     System.out.println(map3.values().stream()
             .map(o -> ((Map<String, Object>)o).values())
             .map(String::valueOf)
             .collect(Collectors.joining(",")));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果: [x, z]

    这里第一个map(o -> ((Map)o).values()) 先获取map3的values 值,第二个 .map(String::valueOf) 获取 map4 的 value值。
    最后进行拼接,一句完成复杂逻辑。

    • 实例对象映射
      对POJO对象的属性拼接也是比较多的,例如:
    // lombok 
    @Data
    @AllArgsConstructor
    private static class User{
        private int id;
        private String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    测试:

     // POJO对象
    
     User user1 = new User(1, "zhangsan");
     User user2 = new User(2, "lisi");
     List<User> users = Arrays.asList(user1, user2);
     System.out.println(users.stream().map(User::getName).collect(Collectors.joining(","))); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    结果: zhangsan,lisi

    3、总结

    拼接的时候也不总是逗号,也可以是其他的内容,例如另外的字符,字符串等。

    以上就差不多是日常coding时遇到的拼接了,应该可以解决所有的情况。

  • 相关阅读:
    基于OpenCV设计的流媒体播放器(RTSP、RTMP)
    Ubuntu22.04:设置Samba服务
    linux 内核漏洞利用 ret2dir
    力扣刷题-字符串-反转字符串
    Pushgetway安装和使用
    基于SSM的邮箱客户端的设计与实现
    pair的用法
    「设计模式」抽象工厂模式
    Redis主从部署
    号称“阿里爸爸”最新Java面试八股文,从最基础的面试题开始
  • 原文地址:https://blog.csdn.net/weixin_42798851/article/details/126155564