gpt4 book ai didi

流中的 Java 8 不同元素

转载 作者:行者123 更新时间:2023-11-29 08:30:38 25 4
gpt4 key购买 nike

我想要最新的和不同的事件。因此,如果产品“球”的事件一天发生 10 次,并且是“踢”类型的事件,那么我只需要有人踢球时的最新事件。

public class Event {
private Date eventDate;
private EventType eventType;
private Long productId;

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;

Event that = (Event) o;

if (eventDate != null ? !eventDate.equals(that.eventDate) : that.eventDate != null)
return false;
if (eventType != that.eventType)
return false;
return productId != null ? productId.equals(that.productId) : that.productId == null;
}

@Override
public int hashCode() {
int result = eventDate != null ? eventDate.hashCode() : 0;
result = 31 * result + (eventType != null ? eventType.hashCode() : 0);
result = 31 * result + (productId != null ? productId.hashCode() : 0);
return result;
}
}

List<Event> events =
actions.getEvent(requestedEvents)
.stream()
.map(event -> new Event(event))
.distinct()
.sorted(Comparator.comparing(Event::getEventDate))
.collect(Collectors.toList());

这不起作用 :( 它获得了不同的事件,但它仍然返回不止一种事件(eventType + productId),我想每对 eventType 和 productId 只返回最新的一个。

我想在不覆盖 equals 和 hashcode 的情况下这样做,但这会更难。

最佳答案

我不确定为此使用 Streams 和 lambdas 是否值得,但现在开始:

Collection<Event> events = allEvents.stream().collect(
Collectors.groupingBy(e -> Arrays.asList(e.getType(), e.getProductId()),
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparing(Event::getEventDate)),
Optional::get))).values();

分解:

  • 生成的集合需要为每个产品和事件类型的组合创建一个事件,因此 Collectors.groupingBy 创建一个映射,其键基于 Arrays.asList(e.getType(), e.getProductId())。
  • Map 中的每个对应值通常都是 List<Event> ,如果使用了单参数 Collectors.groupingBy 方法;因此,我们使用双参数形式代替它,它接受一个应用于 List<Event> 的附加收集器。 .
  • Collectors.maxBy(Comparator.comparing(Event::getEventDate)) 替换了 List<Event>与该列表中的最新事件。但是,由于 maxBy 不能保证列表非空,因此它返回 Optional<Event>。而不是事件实例。
  • 但我们肯定知道每个 List 至少有一个元素(否则它不会首先通过 groupingBy 放置在 Map 中),因此我们可以安全地将每个 Optional 映射到由选修的。为此,我们将 Collectors.maxBy 包装在 Collectors.collectingAndThen 中,它将 maxBy 的结果传递给 Optional::get。
  • 这个大的 Collectors.groupingBy 调用生成的 map 是 Map<List<Object>, Event> .在这一点上,我们可以忽略 map 的键,只返回它的值。

就其值(value)而言,您可以使用 java.util.Objects 类来制作您的 equalshashCode方法更短:

@Override 
public boolean equals(Object o) {
if (o instanceof Event) {
Event that = (Event) o;
return Objects.equals(this.eventDate, that.eventDate) &&
this.eventType == that.eventType &&
Objects.equals(this.productId, that.productId);
}
return false;
}

@Override
public int hashCode() {
return Objects.hash(eventDate, eventType, productId);
}

关于流中的 Java 8 不同元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48566006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com