Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在一组对象中查找字符串属性的连续序列(通过流API)_Java_Java 8_Java Stream - Fatal编程技术网

Java 在一组对象中查找字符串属性的连续序列(通过流API)

Java 在一组对象中查找字符串属性的连续序列(通过流API),java,java-8,java-stream,Java,Java 8,Java Stream,我必须编写一个方法,该方法采用分类数据集和列表。它必须确定是否存在一个连续的MyEvent序列,该序列通过某个类属性表示给定的列表 让我们假设存在以下(代码-)情况: List<String> list = new ArrayList<String>() list.add("AAA"); list.add("BBB"); 该方法正在运行(至少对于这个2元素序列) 是否可以使用流API在单个调用中实现这一点(对于未知大小的序列)? 您的任务并不难,只需创建一个流,应用过滤

我必须编写一个方法,该方法采用
分类数据集
列表
。它必须确定是否存在一个连续的
MyEvent
序列,该序列通过某个类属性表示给定的
列表

让我们假设存在以下(代码-)情况:

List<String> list = new ArrayList<String>()
list.add("AAA");
list.add("BBB");
该方法正在运行(至少对于这个2元素序列)

是否可以使用流API在单个调用中实现这一点(对于未知大小的序列)?


您的任务并不难,只需创建一个
,应用
过滤器
,然后请求最大值。有一个障碍是我们需要谓词中的前一个元素,但我们已经掌握了源集合,它可以提供它

实际上,每个
SortedSet
也是一个
NavigableSet
,它提供了获取上一个元素的方法(如果有),但由于您的要求是支持
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);
}

因此,此方法将向后搜索并在第一个匹配处停止,该匹配已是最大元素,而无需遍历所有元素。

另一种解决方案是使用索引。序列的大小将不限于2

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;
}

有时,最小化成为回答问题的首要要求。我想这就是其中之一,你完全可以摆脱所有的声明和初始化,直接进入业务逻辑,只需要最少的实体细节和测试输入。@Naman好的,我已经这么想了,但我不想回答很多反问题,比如
MyEvent
看起来怎么样等等。。。好的,我将尝试缩短这个问题。
IntStream.range(0,events.size()-1).forEach(I->{MyEvent b=events.get(I+1);List temp=Arrays.asList(events.get(I.缩写,b.缩写);if(temp.equals(sequence)){possibleReturnValues.add(b);})
@HadiJ虽然你的代码看起来很有前途,但我无法返回它,因为它是一个
void
操作,我需要返回
MyEvent
的实例。此外,
events
是一个
SortedSet
,这意味着我无法访问索引。很抱歉,这两个事实加上没有任何解释,使您的代码对我来说毫无用处。无论如何,谢谢你……你不需要归还任何东西。只需使用我的代码而不是你的代码,代码的其他部分是不需要修改的。此外,在我看来,您可以对循环使用
,为了获得更好的性能,还可以添加其他条件<代码>for(int i=0;i
非常感谢您的解释和这两种方法。我可以假设不可能使用单行或单语句流api调用吗?我期待着,但我认为这是可能的。
NavigableSet
是一个非常有用的提示,因为我可以在应用该方法之前将元素存储在这样一个集合中。如上所述,大多数
SortedSet
实现已经是
NavigableSet
。这包括典型的实现,如
TreeSet
TreeMap
的键集。该操作实际上是一个单流语句。为了可读性和避免重复执行
sequence.get(0)
sequence.get(1)
,我只提取了
first
second
。类似地,测试集合是否为
NavigableSet
也可以在函数本身内部完成,但这不会增加可读性和性能。抛开这些准备工作不谈,最后只有一个流操作。好的,谢谢,这回答了所有问题(并对我对单流操作的理解提出了一些问题)。这就是我想要的。您可以这样看:在第二个示例中,
findFirst()
是唯一进行实际数据处理的方法调用。
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);
}
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);
}
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);
}
@Getter
@Setter
@AllArgsConstructor
@ToString
public static class MyEvent implements Comparable<MyEvent> {
  private String abbreviation;
  private LocalDateTime eventTime;

  @Override
  public int compareTo(MyEvent o) {
    return eventTime.compareTo(o.eventTime);
  }
}