I have a java list consisting of objects. Most of the objects have common fields and I need to keep just the one object from the list of candidates that have a specific field set. How can I achieve this? Example
class A{
String field1;
String field2;
String field3;
LocalDate dateField;
}
With the following values;
A first = new A("field1","field2","field3",null);
A second = new A("field1","field2","field3",LocalDate.now());
A third= new A("field1","field2","field3",LocalDate.now().plusMonths(3));
A forth= new A("4","5","6",LocalDate.now().plusMonths(3));
A fifth = new A("7","8","9",LocalDate.now().plusMonths(3));
I need to write a method that returns a list consisting of second, forth and fifth. So if field1 field2 and field3 are identical, I need to keep the minimum localdate field. How to achieve this?
CodePudding user response:
I understand you have a List<A>
of objects of type A
.
It seems want to filter the list, querying it for items A
that match some requirement. What kinds of things you want to search when filtering that list isn't very clear.
List<A> items = ...; // setup the items
List<A> items_filtered = items.stream()
.filter( x -> x.field1.equals("value") )
.collect(Collectors.toList());
List<A> items_filtered_2 = items.stream()
.filter( x -> !x.field2.equals("other_value") )
.collect(Collectors.toList());
These filters can be applied to any list, including list that is the result of a previous filter, or you can combine two checks in the same filter.
List<A> fitlered_both = items.stream()
.filter( x -> x.field1.equals("value") && !x.field2.equals("other_value") )
.collect(Collectors.toList());
CodePudding user response:
You can try this
public static void main(String[] args) {
A first = new A("field1","field2","field3",null);
A second = new A("field1","field2","field3",LocalDate.now());
A third= new A("field1","field2","field3",LocalDate.now().plusMonths(3));
A forth= new A("4","5","6",LocalDate.now().plusMonths(3));
A fifth = new A("7","8","9",LocalDate.now().plusMonths(3));
List<A> collect = Stream.of(first, second, third, forth, fifth)
.collect(
Collectors.groupingBy(a -> Objects.hash(a.field1, a.field2, a.field3),
Collectors.minBy((o1, o2) -> {
if(o1 == null || o2 == null || o1.dateField == null || o2.dateField == null){
return 1;
}
return o1.dateField.compareTo(o2.dateField);
})))
.values().stream().map(Optional::get).collect(Collectors.toList());
System.out.println(collect);
}
You want to group the objects by similar objects first, Objects.hash(field1, field2, field3)
will group objects based on field1
, field2
, and field3
.
Next you want to sort the grouping using Localdate
.
Next, we collect the first elements of each group, which is our answer.
CodePudding user response:
I would suggest to write a comparator and sort the list using it. Then you will be able to retrieve all the desired objects within one pass