我必须写,需要一个方法SortedSet<MyEvent>
和List<String>
。它必须确定是否有一个连续的序列MyEvent
表示给定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
有序列的值。
这是我迄今所做的:
public static void main(String[] args) {
SortedSet<MyEvent> events = generateSomeElements();
List<String> sequence = new ArrayList<>();
sequence.add("AAA");
sequence.add("BBB");
MyEvent desired = getMostRecentLastEventOfSequence(events, sequence);
System.out.println("Result: " + desired.toString());
}
public static MyEvent getMostRecentLastEventOfSequence(SortedSet<MyEvent> events,
List<String> sequence) {
// "convert" the events to a List in order to be able to access indexes
List<MyEvent> myEvents = new ArrayList<MyEvent>();
events.forEach(event -> myEvents.add(event));
// provide a temporary data structure for possible results
SortedSet<MyEvent> possibleReturnValues = new TreeSet<MyEvent>();
// iterate the events in order to find those with a specified predecessor
for (int i = 0; i < myEvents.size(); i++) {
if (i > 0) {
// consider only successive elements
MyEvent a = myEvents.get(i - 1);
MyEvent b = myEvents.get(i);
// check if there is a
if (a.getAbbreviation().equals(sequence.get(0))
&& b.getAbbreviation().equals(sequence.get(1))) {
// if a sequence was found, add the last element to the possible results
possibleReturnValues.add(b);
}
}
}
// check if there were possible results
if (possibleReturnValues.size() == 0) {
return null;
} else {
// if there are any, return the most recent / latest one
return possibleReturnValues.stream().max(MyEvent::compareTo).orElse(null);
}
}
该方法是工作(对于此2元素序列,至少)。
是否有可能做的是,在使用流API(和序列的大小未知)的单次调用?
你的任务并不难,只需要创建一个Stream
,应用filter
,并要求最大值。还有的是,我们需要在谓语前一个元素的障碍,但我们手里源集合,它可以提供它。
在实践中,每SortedSet
也是NavigableSet
它提供了一个lower
方法来获取前一个元素,如果有一个,但由于您的要求是支持SortedSet
输入,我们必须提供一个回退了的理论情况下SortedSet
不是一个NavigableSet
。
然后,操作可以实现为
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
:
public static MyEvent getMostRecentLastEventOfSequence(
SortedSet<MyEvent> events, List<String> sequence) {
String first = sequence.get(0), second = sequence.get(1);
UnaryOperator<MyEvent> previous;
Stream<MyEvent> stream;
if (events instanceof NavigableSet) {
NavigableSet<MyEvent> navigableSet = (NavigableSet<MyEvent>) events;
previous = navigableSet::lower;
stream = navigableSet.descendingSet().stream();
}
else {
previous = event -> events.headSet(event).last();
stream = Stream.iterate(events.last(), previous).limit(events.size());
}
return stream
.filter(event -> event.getAbbreviation().equals(second))
.filter(event -> {
MyEvent p = previous.apply(event);
return p != null && p.getAbbreviation().equals(first);
})
.findFirst().orElse(null);
}
因此,这种方法将在第一场比赛,这将已经是最大的元素向后和停止搜索,而不需要遍历所有元素。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句