簡體   English   中英

Java - 如何改進此功能(Java 8 流)

[英]Java - how to improve on this function (Java 8 streams)

我編寫了一個函數,該函數根據此處的示例使用 Java 8 流查找字符串中的唯一字符。

對我來說,這很不直觀,也許是因為我還在學習流。 有什么方法可以使這更具可讀性?

這是代碼:

    public static void main(String[] args) {

        String str = "aabcddeffg";

        char[] charArray = str.toCharArray();

        List<String> strList = new ArrayList<>();
        for(int i=0; i< charArray.length; i++){
            String myChar = String.valueOf(charArray[i]);
            strList.add(myChar);
        }

        Map<String, Long> myMap =
                strList.stream().
                        collect(
                                Collectors.groupingBy(
                                        Function.identity(),Collectors.counting()
                                )
                        );

        myMap.forEach((k, v) -> {
            if (v == 1) {
                System.out.println(k);
            }
        });

    }
}

為了計算實際頻率,您幾乎已經是一個最小的例子了!

Map<Integer, Long> charFrequency = strList.stream() //Stream<String>
            .flatMapToInt(String::chars)  //Stream<IntStream> -> IntStream
            .boxed() //IntStream -> Stream<Integer>
            .collect(Collectors.groupingBy( //Map<K, V>
                    Function.identity(), //K == our integers
                    Collectors.counting() //V == the number of them
            ));

charFrequency.entrySet().stream() //Stream<Map.Entry<Integer, Long>>
            .filter(ent -> ent.getValue() == 1) //only entries with value of 1
            .mapToInt(Map.Entry::getKey) //Stream<Entry> -> IntStream
            .forEach(c -> {
                System.out.println("Found unique character: " + ((char) c));
            });

對於單個字符串,它甚至更容易(您保存轉換):

Map<Integer, Long> charFrequency = someString.chars() //Stream<Integer>
            .collect(Collectors.groupingBy( //Map<K, V>
                    Function.identity(), //K == our integers
                    Collectors.counting() //V == the number of them
            ));

為此,我會確保您的代碼是一致且可讀的。 例如,使用一致的縮進並注釋流如何每行步進。

編輯:我留下了以下(舊)答案只是為了給 OP 提供信息,但它沒有回答實際問題。

好吧,總是有Stream#distinct

計算“不同”(非唯一)字符:

List<Integer> distinctChars = strList.stream() //Stream<String>
        .flatMapToInt(String::chars)  //Stream<IntStream> -> IntStream
        .distinct() //unique IntStream
        .boxed() //unique Stream<Integer>
        .collect(Collectors.toList()); //List<Integer>

distinctChars.forEach(c -> {
    System.out.println("Found distinct char: " + ((char) (int) c));
});

如果你想避免收集它,你也可以避免圍繞類型拳擊的所有麻煩:

strList.stream() //Stream<String>
        .flatMapToInt(String::chars)  //Stream<IntStream> -> IntStream
        .distinct() //unique IntStream
        .forEach(c -> {
            System.out.println("Found distinct char: " + ((char) c));
        });

這里是一種相當晦澀的方法。

  • 創建一個0string length的流。
  • 現在查找從 i+1 開始的字符串是否有任何從 i 開始的字符,如果是,它必須是重復的。
  • 所以在流中傳遞索引。
  • 然后將該索引映射到實際字符。
  • 並通過刪除所有重復項來減少原始字符串的副本。

String str = "aabcddeffg";

String result = IntStream.range(0,str.length())
.filter(i->str.substring(i+1)
        .indexOf(str.charAt(i)) >= 0 )
.mapToObj(i->str.substring(i,i+1)).reduce(str, (a,b)->a.replace(b,""));

System.out.println(result);

印刷

bceg

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM