Java - How to get list of elements best on certain condition

user1298426 :
Solution{
  String question
  String answer

  public Solution(String question,String answer){
  ...
  }
}

List<Solution> solutions = new ArrayList<>();

Arrays.asList(
    new Solution("Index1","a"),
    new Solution("Index2","b"),
    new Solution("Index3","c"),
    new Solution("Index4","d"),
    new Solution("Index5","ae"),
    new Solution("Index1","afg"),
    new Solution("Index2","adfg"),
    new Solution("Index1","ag"),
    new Solution("Index2","a"),
    new Solution("Index3","a"),
    new Solution("Index4","a"),
    new Solution("Index5","a"),
    new Solution("Index1","arrr"),
    new Solution("Index2","a"),
    new Solution("Index3","a"));

I always want to get last two sets starting from Index1 which are

new Solution("Index1","ag"),
new Solution("Index2","a"),
new Solution("Index3","a"),
new Solution("Index4","a"),
new Solution("Index5","a"),
new Solution("Index1","arrr"),
new Solution("Index2","a"),
new Solution("Index3","a"))

but I am not sure what is the best way to do that. I can think of reversing the list and then have a counter on Index1 which starts with 0 then do while loop to add it in a list until counter reaches 2. Not sure if this is possible with streams.

Stuart Marks :

I think the simplest way is to get the positions at which Index1 occurs in the list of solutions. These represent potential start position of the sublist. You can do this by using an IntStream over the indexes into the solutions list. Then, take the second-to-last start point as the starting of a sublist that goes to the end of the list.

    List<Integer> starts = IntStream.range(0, solutions.size())
                                    .filter(i -> solutions.get(i).getQuestion().equals("Index1"))
                                    .boxed()
                                    .collect(toList());
    if (starts.size() < 2) {
        // not sure what you want to do in this case
    } else {
        List<Solution> lastTwoSets = solutions.subList(starts.get(starts.size()-2), solutions.size());
        lastTwoSets.forEach(System.out::println);
    }

It occurs to me that using an int[] instead of List<Integer> makes things slightly more efficient as well as a bit more concise. The techique is otherwise essentially the same.

    int[] starts = IntStream.range(0, solutions.size())
                            .filter(i -> solutions.get(i).question.equals("Index1"))
                            .toArray();
    if (starts.length < 2) {
        // not sure what you want to do in this case
    } else {
        List<Solution> lastTwoSets = solutions.subList(starts[starts.length-2], solutions.size());
        lastTwoSets.forEach(System.out::println);
    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=93009&siteId=1