如何使用流 API 过滤连续元素?

Eri*_* B. 1 java java-stream

我想知道是否有办法使用 java 的流 API 过滤连续/互连的元素?

为您提供此问题的背景:我检索了包含不同停靠点的交通线列表。作为用户,我现在只想知道从 X 到 Y 的路线上的旅行时间和站点。所以我需要过滤所有相互连接的路段(停止 a -> 停止 b)。

我有一个未排序的对象列表,其中包含字段startend。我现在想检索一个列表,该列表仅包含在这两个点之间逻辑连接的元素。这里有一个简单的例子:

我想过滤开始 B结束 E

List to filter: {A,B},{B,C},{C,D},{D,E},{E,F}
List I want:    {B,C},{C,D},{D,E}
Run Code Online (Sandbox Code Playgroud)

Scr*_*tte 5

正如我在评论中所说,Streams API 不适用于有状态操作。使用的比较Comparator是不是因为比较可行{D,E}{Q,A}可能应该未定义或为空。这排除了该sorted?(Comparator<? super T> comparator)方法。我也不认为将元素复杂地排序为 aLinkedList也没有意义。

我认为一个更简单的解决方案是将您的元素放入地图中。并基于此获取下一个元素。

你的符号

过滤列表:{A,B},{B,C},{C,D},{D,E},{E,F}

看起来有点像数组列表,所以这就是我所用的。

一旦数组被映射到它们的键,这只是数组的第一个元素,你可以按照基于键获取下一个数组的路径:

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import java.util.stream.Collectors;

public class StackOverflowTest3 {
  public static void main(String[] args) {

    // The full route starts in Vilnius and ends in Seattle
    List<String[]> unsortedList
        = new ArrayList<>(List.of(new String[]{"Copenhagen","Amsterdam"},
                                  new String[]{"Vilnius","Riga"},
                                  new String[]{"Rotterdam","New York"},
                                  new String[]{"Chicago","Seattle"},
                                  new String[]{"Amsterdam","Rotterdam"},
                                  new String[]{"New York","Chicago"},
                                  new String[]{"Riga","Copenhagen"}));

    // Put the entries into a map:
    Map<String,String[]> map = new HashMap<>(8); // initial capacity = 8
    for (String[] arr : unsortedList) {
      map.put(arr[0], arr);
    }
/*
    // Alternatively, if you really like the streams API:
    Map<String,String[]> map
        = unsortedList.stream()
                      .collect(Collectors.toMap(s -> s[0],
                                                s -> s,
                                                (a,b) -> a)); // in case there are two mappings
*/

    // fetch the transits from Copenhagen to Chicago for printing:
    String begin = "Copenhagen";
    String end   = "Chicago";
    String next  = begin;

    System.out.println("Just transits:");
    System.out.print(begin);
    while (!next.equals(end)) {
       next = map.get(next)[1];
       System.out.print(" -> " + next);  
    }
    System.out.println();
    System.out.println();


    // fetch the transits from Copenhagen to Chicago back to a new list:
    next = begin;  // starting over
    List<String[]> sortedLimitedList = new ArrayList<>(8);

    while (!next.equals(end)) {
      String[] current = map.get(next); 
      next = current[1];
      sortedLimitedList.add(current);
    }

    System.out.println("List of Start, End:");    
    sortedLimitedList.stream()
                     .forEach(a -> System.out.print(Arrays.toString(a)));
    System.out.println();
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

Just transits:
Copenhagen -> Amsterdam -> Rotterdam -> New York -> Chicago

List of Start, End:
[Copenhagen, Amsterdam][Amsterdam, Rotterdam][Rotterdam, New York][New York, Chicago]
Run Code Online (Sandbox Code Playgroud)