如何从 java 流中收集优先值?
How collect prioritized values from java streams?
是否可以收集优先流,以便我区分某个对象并过滤另一个对象的最大值?
示例:
class Foo {
private LocalDate date;
private Integer cash;
}
List<Foo> myNewFoo = foos.stream().distinct(SOMETHING).collect(toList())
// distinct date, if more than one date of same value then choose max value of cash.
试试这个。
List<Foo> foos = List.of(
new Foo(LocalDate.of(2021, 1, 1), 100),
new Foo(LocalDate.of(2021, 1, 1), 200),
new Foo(LocalDate.of(2021, 1, 2), 300),
new Foo(LocalDate.of(2021, 1, 2), 400),
new Foo(LocalDate.of(2021, 1, 3), 500));
List<Foo> myNewFoo = new ArrayList<>(foos.stream()
.collect(Collectors.toMap(Foo::getDate, Function.identity(),
(a, b) -> a.getCash() > b.getCash() ? a : b, TreeMap::new))
.values());
System.out.println(myNewFoo);
输出:
[Foo(2021-01-01,200), Foo(2021-01-02,400), Foo(2021-01-03,500)]
一个选项是:按 cash
降序排列对象。然后使用包装 Set
的方法来跟踪已经看到的日期并用它过滤流(Set::add
returns 如果它还没有包含指定的元素则为真)。
public static void main(String[] args) {
List<Foo> foos = new ArrayList<>();
foos.add(new Foo(LocalDate.of(2021, 6, 1), 600));
foos.add(new Foo(LocalDate.of(2021, 6, 3), 200));
foos.add(new Foo(LocalDate.of(2021, 6, 4), 300));
foos.add(new Foo(LocalDate.of(2021, 6, 2), 400));
foos.add(new Foo(LocalDate.of(2021, 6, 3), 800));
foos.add(new Foo(LocalDate.of(2021, 6, 1), 300));
List<Foo> myNewFoo = foos.stream()
.sorted(Comparator.comparing(Foo::getCash).reversed())
.filter(distinctByDate())
.collect(Collectors.toList());
System.out.println(myNewFoo);
}
public static Predicate<Foo> distinctByDate() {
Set<LocalDate> seen = new HashSet<>();
return foo -> seen.add(foo.getDate());
}
结果:
[(2021-06-03,800), (2021-06-01,600), (2021-06-02,400), (2021-06-04,300)]
是否可以收集优先流,以便我区分某个对象并过滤另一个对象的最大值?
示例:
class Foo {
private LocalDate date;
private Integer cash;
}
List<Foo> myNewFoo = foos.stream().distinct(SOMETHING).collect(toList())
// distinct date, if more than one date of same value then choose max value of cash.
试试这个。
List<Foo> foos = List.of(
new Foo(LocalDate.of(2021, 1, 1), 100),
new Foo(LocalDate.of(2021, 1, 1), 200),
new Foo(LocalDate.of(2021, 1, 2), 300),
new Foo(LocalDate.of(2021, 1, 2), 400),
new Foo(LocalDate.of(2021, 1, 3), 500));
List<Foo> myNewFoo = new ArrayList<>(foos.stream()
.collect(Collectors.toMap(Foo::getDate, Function.identity(),
(a, b) -> a.getCash() > b.getCash() ? a : b, TreeMap::new))
.values());
System.out.println(myNewFoo);
输出:
[Foo(2021-01-01,200), Foo(2021-01-02,400), Foo(2021-01-03,500)]
一个选项是:按 cash
降序排列对象。然后使用包装 Set
的方法来跟踪已经看到的日期并用它过滤流(Set::add
returns 如果它还没有包含指定的元素则为真)。
public static void main(String[] args) {
List<Foo> foos = new ArrayList<>();
foos.add(new Foo(LocalDate.of(2021, 6, 1), 600));
foos.add(new Foo(LocalDate.of(2021, 6, 3), 200));
foos.add(new Foo(LocalDate.of(2021, 6, 4), 300));
foos.add(new Foo(LocalDate.of(2021, 6, 2), 400));
foos.add(new Foo(LocalDate.of(2021, 6, 3), 800));
foos.add(new Foo(LocalDate.of(2021, 6, 1), 300));
List<Foo> myNewFoo = foos.stream()
.sorted(Comparator.comparing(Foo::getCash).reversed())
.filter(distinctByDate())
.collect(Collectors.toList());
System.out.println(myNewFoo);
}
public static Predicate<Foo> distinctByDate() {
Set<LocalDate> seen = new HashSet<>();
return foo -> seen.add(foo.getDate());
}
结果:
[(2021-06-03,800), (2021-06-01,600), (2021-06-02,400), (2021-06-04,300)]