[英]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};
這可以用一個簡單的賦值替換一系列if
或switch
這可以通過 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.