无法计算字符串的每个部分有多少个唯一日期可用

问题描述

我使用换行符 ('\n') 将字符串分成三部分。我想要实现的输出:计算字符串的每个部分中有多少唯一日期可用。
根据下面的代码,第一部分包含两个唯一的日期,第二部分包含两个,第三部分包含三个唯一的日期。所以输出应该是这样的:2,2,3,
但是在运行下面的代码后,我得到了这个输出:5,5,1,
我如何获得输出:2,
提前致谢。

        String strH;
        String strT = null;
        StringBuilder sbE = new StringBuilder();
        String strA = "2021-03-02,2021-03-02,2021-03-11," + '\n' +
                "2021-03-07,2021-03-07,2021-03-15," + '\n' +
                "2021-03-02,2021-03-09,";

        String[] strG = strA.split("\n");
        for(int h=0; h<strG.length; h++){
            strH = strG[h];
            String[] words=strH.split(",");
            int wrc=1;
            for(int i=0;i<words.length;i++) {
                for(int j=i+1;j<words.length;j++) {
                    if(words[i].equals(words[j])) {
                        wrc=wrc+1;
                        words[j]="0";
                    }
                }
                if(words[i]!="0"){
                    sbE.append(wrc).append(",");
                    strT = String.valueOf(sbE);
                }
                wrc=1;
            }
        }
        Log.d("TAG","Output: "+strT);

解决方法

我会在这里使用一个集合来计算重复项:

String strA = "2021-03-02,2021-03-02,2021-03-11,2021-03-11" + "\n" +
              "2021-03-07,2021-03-07,2021-03-15,2021-03-15" + "\n" +
              "2021-03-02,2021-03-09,2021-03-09";
String[] lines = strA.split("\n");
List<Integer> counts = new ArrayList<>();
for (String line : lines) {
    counts.add(new HashSet<String>(Arrays.asList(line.split(","))).size());
}
System.out.println(counts);  // [2,2,3]

请注意,我通过删除每一行的尾随逗号对 strA 输入进行了小幅清理。

,

使用 Java 8 Streams,这可以在单个语句中完成:

String strA = "2021-03-02," + '\n' +
              "2021-03-07," + '\n' +
              "2021-03-02,";

String strT = Pattern.compile("\n").splitAsStream(strA)
        .map(strG -> String.valueOf(Pattern.compile(",").splitAsStream(strG).distinct().count()))
        .collect(Collectors.joining(","));

System.out.println(strT); // 2,3

注意 Pattern.compile("\n").splitAsStream(strA) 也可以写成 Arrays.stream(strA.split("\n")),这样写起来更短,但是会创建一个不必要的中间数组。看个人喜好哪个更好。

String strT = Arrays.stream(strA.split("\n"))
        .map(strG -> String.valueOf(Arrays.stream(strG.split(",")).distinct().count()))
        .collect(Collectors.joining(","));

第一个版本可以通过只编译一次正则表达式来进一步微优化:

Pattern patternComma = Pattern.compile(",");
String strT = Pattern.compile("\n").splitAsStream(strA)
        .map(strG -> String.valueOf(patternComma.splitAsStream(strG).distinct().count()))
        .collect(Collectors.joining(","));