So first of all in the description You say that
A train has the attributes Id, Color, Wagon.
But, later in the example:
finalList = trains.stream()
.filter(tr -> wagons.stream()
.anyMatch(wg ->tr.getWagons()
.foreach(trWg -> trWg.getId().equals(wg.getId()))));
Therefore I assume that the first one was true, and for some reason your train can have only one wagon for now
There are several solutions to this "problem":
First and the cleanest method in my opinion:
List<Wagon> wagons = new ArrayList<>();
wagons.add(new Wagon(0L, new ArrayList<>(), "0"));
wagons.add(new Wagon(1L, new ArrayList<>(), "1"));
List<Train> trains = new ArrayList<>();
trains.add(new Train(0L, wagons.get(0), "Yellow"));
trains.add(new Train(1L, wagons.get(1), "Blue"));
trains.add(new Train(2L, new Wagon(12L, new ArrayList<>(), "not in wagon list"), "Blue"));
List<Train> finalList = trains.stream().
filter(train -> wagons.contains(train.getWagon()))
.collect(Collectors.toList());
finalList.forEach(System.out::println);
And ofc POJO'S
@Getter
@AllArgsConstructor
@ToString
class Train {
private Long id;
private Wagon wagon;
private String color;
}
@Getter
@ToString
@AllArgsConstructor
@EqualsAndHashCode
class Wagon {
private Long id;
private List<String> seats;
private String type;
}
But you have to remember here to implement equals() for Wagon
Second method without the need of implementing the equals() is:
List<Train> finalList2 = trains.stream()
.filter(train -> wagons
.stream()
.anyMatch(wagon -> wagon.getId().equals(train.getWagon().getId())))
.collect(Collectors.toList());
Now assume that your train can have more than one wagon...
@Getter
@AllArgsConstructor
@ToString
class Train {
private Long id;
private List<Wagon> wagons;
private String color;
}
And the code:
List<Wagon> wagons = new ArrayList<>();
wagons.add(new Wagon(0L, new ArrayList<>(), "0"));
wagons.add(new Wagon(1L, new ArrayList<>(), "1"));
List<Wagon> wagons2 = new ArrayList<>();
wagons2.add(new Wagon(11L, new ArrayList<>(), "11"));
wagons2.add(new Wagon(12L, new ArrayList<>(), "12"));
List<Train> trains = new ArrayList<>();
trains.add(new Train(0L, wagons,"Yellow"));
trains.add(new Train(1L, wagons2, "Blue"));
trains.add(new Train(2L, Arrays.asList(new Wagon(132L, new ArrayList<>(),"not in wagon list")), "Blue"));
List<Train> finalList3 = trains.stream()
.filter(train -> train.getWagons().containsAll(wagons))
.collect(Collectors.toList());
finalList3.forEach(System.out::println);
As long as you assume, that you are interested only in trains containing exact set of wagons. And equals() is necessary for this method too!
.isEmpty()?containsAllwould mean the train has all the wagons.retainAllought to work (although modify!) - is there a dodgyequalsmethod?.getWagons.a method (one that copies theList)?finalListbeing empty impliesretainAllreturns false, i.e. no modification. Even for a train with no wagons? Otherwise I would expect anequalsmethod always returningfalse.wagonfrom the list and another one astrain's attribute might be different instances (different @). It all depends on how the two wagons have been instantiated, in case the list is filled with wagons from train, then you can compare both objects, otherwise you should implement you own comparator method.