簡體   English   中英

使用 Java 流轉換具有多個 if/else 的經典嵌套循環

[英]Convert classic nested loops with multiple if/else with Java streams

我需要一些關於使用 Java Streams 可以在此處完成的操作的指導。 我有 test[][] object 的二維數組,其中包含行、列和值。 為了產生不同的表示,我循環並手動 append 不同的字符來做到這一點。

public class Test{
    private Point[][] test;   // like a rectangle
    ...
}

public String someFunction() {
    StringBuilder result = new StringBuilder(150);
    for (int row = 0; r < 10; row++) {
        for (int col = 0; c < 15; col++) {
            if (test[row][col].getVal() == 1) {
                result.append('L');
            } else if (test[row][col].getVal() == 2) {
                result.append('M');
            } else if (test[row][col].getVal() == 10) {
                result.append('N');
            } else {
                result.append(' ');
            }
        }
        result.append('\n');
    }
    return result.toString();
 }

此外,通常流如何與 2 個循環一起工作,一些很好的例子會很有幫助。

為了簡化這段代碼,您可以使用for-each循環,這樣您就不需要處理索引

public String someFunction() {
    for (C[] row : test) {
        for (C item : row) {
            if (item.getVal() == 1) {
                result.append('L');
            } else if (item.getVal() == 2) {
                result.append('M');
            } else if (item.getVal() == 10) {
                result.append('N');
            } else {
                result.append(' ');
            }
        }
        result.append('\n');
    }
    return result.toString();
}

使用 Stream 版本不會贏得任何東西,因為您正在做簡單的事情,只是迭代一個數組,所以經典循環很好,但在這里

public static String someFunction() {
    return Arrays.stream(test)
            .map(row -> Arrays.stream(row).map(item -> {
                switch (item.getVal()) {
                    case 1:
                        return "L";
                    case 2:
                        return "M";
                    case 10:
                        return "N";
                    default:
                        return " ";
                }
            }).collect(Collectors.joining()))
            .collect(Collectors.joining("\n"));
}

如果你想看的話,Stream 版本的索引

public String someFunction() {
    return IntStream.range(0, test.length).mapToObj(rowIdx -> IntStream.range(0, test[rowIdx].length).mapToObj(colIdx -> {
        switch (test[rowIdx][colIdx].getVal()) {
                    ...
        }
    }).collect(Collectors.joining())).collect(Collectors.joining("\n"));
}

我將 int 映射到 char 的解決方案是使用 char 數組。

char[] intToChar = {' ', 'L', 'M', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'N};

這可以用一個簡單的賦值替換一系列ifswitch

這可以通過 String 和方法charAt(i)變得更簡單

這是 Azro 答案的一個細微變化,因為我基本上已經寫過了。

如果索引很重要(即由於某種原因您只想對完整“網格”的一部分執行計算),那么Arrays.stream有另一個簽名,您可以在其中指定這些,就像您在答案中所做的那樣。

從 Java 14 開始,您可以使用 switch 表達式使從點值到字符的轉換更好一點。

您還可以使用與迭代示例類似的方式使用StringBuilder Collectors.joining以類似的方式工作,但它無法預先分配適量的空間。 幾乎可以肯定與 150 個字符無關,但無論如何我認為這是一個有趣的例子。

return Arrays.stream(test, 0, 10)
    .map(row -> Arrays.stream(row, 0, 15)
        .map(ValueSource::getVal)
        .map(val -> switch(val) {
            case 1 ->  'L';
            case 2 ->  'M';
            case 10 -> 'N';
            default -> ' ';
        })
        .collect(Collector.of(() -> new StringBuilder(row.length), StringBuilder::append, StringBuilder::append))
    )
    .collect(Collector.of(() -> new StringBuilder(150), StringBuilder::append, StringBuilder::append, StringBuilder::toString));

暫無
暫無

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

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