I'm trying to filter two conditions in a stream that is inside another stream of data, what I need to do is to check if the object is there by using the "name" parameter and then reviewing the Boolean property of "isGoldplated" if is true, I tried using this code but didn't work as it wasn't filtering by the isGoldplated parameter:
List<CompressorModel> filteredCompressors = pack.getSet().getCompressors().stream()
.peek(p -> goldData.stream().map(GoldPlateData::getCompressorSerialNo).anyMatch(name -> name.equals(p.getGcsn())))
.peek(p -> goldData.stream().map(GoldPlateData::getIsGoldplated))
.collect(Collectors.toList());
so I finished using two loops instead:
List<CompressorModel> filteredCompressors = new ArrayList<>();
for (CompressorModel cmp : pack.getSet().getCompressors()) {
for(GoldPlateData gold: goldData) {
if( StringUtils.equalsIgnoreCase(cmp.getGcsn(), gold.getCompressorSerialNo()) && Boolean.TRUE.equals(gold.getIsGoldplated())) {
filteredCompressors.add(cmp);
}
}
}
so my request is, how could I convert these two loops into a working stream?
thanks in advance
CodePudding user response:
You could use filter()
on the pack.getSet().getCompressors()
stream and then look for a match in goldData
, like this:
List<CompressorModel> filteredCompressors = pack.getSet()
.getCompressors().stream()
.filter(cmp -> goldData.stream().anyMatch(gd -> cmp.getGcsn().equalsIgnoreCase(gd.getCompressorSerialNo()) && gd.getIsGoldplated()))
.collect(Collectors.toList());
CodePudding user response:
Peek is basically there only to be used for debugging purposes. Peek can be not executed at all at times because it's a terminal operation. You can see here to get an idea.
So you may modify your implementation to use filter instead.
List<CompressorModel> filteredCompressors = pack.getSet().getCompressors().stream()
.filter(p -> goldData.stream().map(GoldPlateData::getCompressorSerialNo).anyMatch(name -> name.equals(p.getGcsn())))
.filter(p -> goldData.stream().map(GoldPlateData::getIsGoldplated))
.collect(Collectors.toList());