我必须编写一个采用SortedSet<MyEvent>
和List<String>
的方法。它必须确定是否存在由某个类属性表示给定MyEvent
的{{1}}的连续序列。
假设存在以下(代码)情况:
List<String>
和一个List<String> list = new ArrayList<String>()
list.add("AAA");
list.add("BBB");
Set<MyEvent>
具有SortedSet<MyEvent> events = new TreeSet<MyEvent>();
类型的MyEvent
对象(仅与implements Comparable<MyEvent>
比较)。
给定的LocalDateTime
代表一个缩写序列,我需要查找最近出现的List<String>
序列,其类属性MyEvent
具有该序列的值。
这是我到目前为止所做的:
abbreviation
该方法有效(至少对于此2元素序列而言)。
是否可以使用流API在一次调用中完成此操作(序列大小未知)?
答案 0 :(得分:3)
您的任务并不难,只需创建一个Stream
,应用一个filter
,然后索取最大值。在谓词中需要一个前一个元素是有障碍的,但是我们可以动手使用可以提供它的源集合。
实际上,每个SortedSet
也是一个NavigableSet
,它提供了一种lower
方法来获取前一个元素(如果有),但是由于您的要求是支持{{ 1}}输入,我们必须为SortedSet
不是SortedSet
的理论情况提供后备。
然后,该操作可以实现为
NavigableSet
但是我们可以做得更好。由于我们现在正在搜索 sorted 输入中的最大值,因此我们知道向后迭代时,第一个匹配就足够了。同样,当输入实际上是public static MyEvent getMostRecentLastEventOfSequence(
SortedSet<MyEvent> events, List<String> sequence) {
String first = sequence.get(0), second = sequence.get(1);
UnaryOperator<MyEvent> previous;
if (events instanceof NavigableSet) {
NavigableSet<MyEvent> navigableSet = (NavigableSet<MyEvent>) events;
previous = navigableSet::lower;
}
else previous = event -> events.headSet(event).last();
return events.stream()
.filter(event -> event.getAbbreviation().equals(second))
.filter(event -> {
MyEvent p = previous.apply(event);
return p != null && p.getAbbreviation().equals(first);
})
.max(Comparator.naturalOrder()).orElse(null);
}
时,会更加平滑:
NavigableSet
因此,此方法将向后搜索并在第一个匹配项处停止,该匹配项已经是最大元素,而无需遍历所有元素。
答案 1 :(得分:1)
另一个解决方案是使用索引。序列的大小不限于2。
Private Sub PurchaseOrder_BeforeUpdate(Cancel As Integer)
Cancel = IsNull(Me!PurchaseOrder.Value)
End Sub
这是示例测试代码:
public static MyEvent getMostRecentLastEventOfSequence(SortedSet<MyEvent> events, List<String> sequence) {
final List<MyEvent> eventList = new ArrayList<>(events);
Collections.reverse(eventList);
final int seqLength = sequence.size();
OptionalInt first = IntStream.range(0, eventList.size() - seqLength + 1)
.filter(i -> IntStream.range(0, seqLength)
.allMatch(j -> eventList.get(i + j).getAbbreviation().equals(sequence.get(seqLength - j - 1))))
.findFirst();
return first.isPresent() ? eventList.get(first.getAsInt()) : null;
}
带有@Test
void test_56005015() throws Exception {
List<String> sequence = Arrays.asList("AAA", "BBB", "CCC");
SortedSet<MyEvent> events = new TreeSet<>();
events.add(new MyEvent("AAA", LocalDateTime.now().plusDays(1)));
events.add(new MyEvent("BBB", LocalDateTime.now().plusDays(2)));
events.add(new MyEvent("CCC", LocalDateTime.now().plusDays(3)));
events.add(new MyEvent("AAA", LocalDateTime.now().plusDays(4)));
events.add(new MyEvent("BBB", LocalDateTime.now().plusDays(5)));
events.add(new MyEvent("CCC", LocalDateTime.now().plusDays(6)));
MyEvent result = getMostRecentLastEventOfSequence(events, sequence);
System.out.println(result);
}
类并带有MyEvent
的注释。
Lombok