Reputation: 83
I need some guidance on what can be done here using Java Streams. I have the 2D Arrray of test[][] object which holds row, col and value inside. in order to produce different representation, I loop through and manually append different characters to do that.
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();
}
Also, Generally how does the streams work with 2 loops, some good examples would be great help.
Upvotes: 0
Views: 441
Reputation: 44130
Here's a slight variation of Azro's answer, since I'd basically already written it.
If the indices are important (i.e. for some reason you want to perform the calculation only on a portion of the full "grid") then Arrays.stream
has another signature where you can specify those, just as you did in your answer.
From Java 14, you can use switch expressions to make the conversion from point value to character a bit nicer.
You can also also use StringBuilder
s in a similar way as your iterative example. Collectors.joining
works in a similar way but it is not able to pre-allocate the right amount of space. Almost certainly irrelevant for 150 characters, but I thought it made an interesting example anyway.
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));
Upvotes: 0
Reputation: 54148
To simplify a bit this code, you can use for-each
loops, this way you won't need to handle indexes
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();
}
You won't win something by using the Stream version because you're doing easy thing just iterating an array so the classic loop is nice, but here it is
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"));
}
And if you want to see it, the Stream version with the indices
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"));
}
Upvotes: 1
Reputation: 14328
my solution for the mapping of int to char is to use char array.
char[] intToChar = {' ', 'L', 'M', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'N};
this can replace the series of if
or switch
with a simple assignment
this can be made simpler with a String and the method charAt(i)
Upvotes: 0