어떻게 하위 목록 특정 경기에서 시작하여 Java 스트림 API에 의해 다른 경기로 끝나는를 얻으려면?

deHaar :

나는이에 관심이 stream의 하위 목록을 얻을 Y 방식으로 정렬 된 객체의 목록입니다. 하위 목록은 그 속성 중 하나에 관한 주어진 조건에 일치하는 객체로 시작해야하며 다른 조건에 일치하는 객체로 끝나야합니다.

하자 말, 나는 다음과 같은 클래스가 Element:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Element implements Comparable<Element> {

    String abbreviation;
    LocalDateTime creationTime;

    public Element(String abbreviation, LocalDateTime creationTime) {
        this.abbreviation = abbreviation;
        this.creationTime = creationTime;
    }

    public String getAbbreviation() {
        return abbreviation;
    }

    public void setAbbreviation(String abbreviation) {
        this.abbreviation = abbreviation;
    }

    public LocalDateTime getCreationTime() {
        return creationTime;
    }

    public void setCreationTime(LocalDateTime creationTime) {
        this.creationTime = creationTime;
    }

    @Override
    public int compareTo(Element otherElement) {
        return this.creationTime.compareTo(otherElement.getCreationTime());
    }

    @Override
    public String toString() {
        return "[" + abbreviation + ", "
                + creationTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + "]";
    }
}

나는 수신 List<Element>에 의해 주문되는을 creationTime. 지금은 단지 그들의 관한 두 가지 특정 것들 사이의 요소가 있는지 확인하려면 abbreviation. 내가 알고있는 방법을 filter하나의 요소 또는 주어진 일치하는 요소의 목록 abbreviation사용 findFirst()또는 findAny()Collectors.toList(). 그러나, 나는 그냥 특정과 하위 목록의 처음 찾는 방법을 모르는 abbreviation사이에 할 일의 요소 (그리고해야) 조건과 일치하지 두 개의 다른 조건이 있기 때문에 또 다른 하나 및 종료합니다.

나는 다음과 같은 있다고 가정 List<Element>(-generating 방법) :

private static List<Element> generateSomeElements() {
    List<Element> elements = new ArrayList<Element>();

    LocalDateTime now = LocalDateTime.now();

    Element elementOne = new Element("ABC", now.minus(14, ChronoUnit.DAYS));
    Element elementTwo = new Element("DEF", now.minus(13, ChronoUnit.DAYS));
    Element elementThree = new Element("GHI", now.minus(12, ChronoUnit.DAYS));
    Element elementFour = new Element("JKL", now.minus(11, ChronoUnit.DAYS));
    Element elementFive = new Element("MNO", now.minus(10, ChronoUnit.DAYS));
    Element elementSix = new Element("PQR", now.minus(9, ChronoUnit.DAYS));
    Element elementSeven = new Element("STU", now.minus(8, ChronoUnit.DAYS));
    Element elementEight = new Element("VWX", now.minus(7, ChronoUnit.DAYS));
    Element elementNine = new Element("YZ1", now.minus(6, ChronoUnit.DAYS));
    Element elementTen = new Element("234", now.minus(5, ChronoUnit.DAYS));

    elements.add(elementOne);
    elements.add(elementTwo);
    elements.add(elementThree);
    elements.add(elementFour);
    elements.add(elementFive);
    elements.add(elementSix);
    elements.add(elementSeven);
    elements.add(elementEight);
    elements.add(elementNine);
    elements.add(elementTen);

    return elements;
}

나는 (포함)에서 하위 목록이 필요 "MNO"(포함)에 "YZ1"이탈,이 소스 목록에있는 순서를 유지 creationTime옆을 .

나는 (의 인덱스 찾는처럼 스트림을 사용하지 않고 그렇게하는 방법을 알고 시작끝을 인덱스의 요소 후 점점 start인덱스에 end충분하지만, 어떻게 든 수도) - 구식 정말 현대적인 API를 이용하기위한 내 욕심을 만족하지합니다.

나는 그것을 작동하게하는 방법을 추가 할 수 있습니다,하지만 그들은 그냥 하나의 스트림 문을 사용하여 해결할 수없는 나는 문제를 설명하는 또 다른 형태의 것이다. 또한, 그 방법은 일반적인 가능성을 묻는 다른 질문의 다양한 설명과 스트림 API를 대상으로하지 않습니다.

일반적 :
두 가지 조건은 다음과 List<Element>하위 목록은 그 첫 번째 요소 수집 될 위치는 그 마지막 요소 한 정합 상태 1 인 것이 하나의 정합 조건이 그 사이의 모든 요소는도 수집하고, 주문하게 유지되는 반면 이 기원이다.

단일 스트림 API 문을 사용하여 원하는 하위 목록을 얻기의 가능성을 알고있는 경우에 그래서, 대답으로 추가하십시오.

나는 한 번 봐 것입니다 reduce()그 동안 방법을, 어쩌면 그 신비에 대한 답변입니다 ...

편집
내가 사용하는 나에게 원하는 결과를 제공하는 솔루션을 발견 stream()전화를하지만 그 중 세 가지가 필요합니다. 첫 번째 조건에 일치하는 요소 번째 두 번째 조건에 대한 매칭 소자를 발견하여 사용 하나 원하는 서브리스트 인출 한 후, 인출 한 creationTime처음 두에서 발견 된 두 요소들 stream()들 :

public static void main(String[] args) {
    List<Element> elements = generateSomeElements();

    // print origin once followed by a horizontal separator for the human eye
    elements.forEach(element -> System.out.println(element.toString()));

    System.out.println("————————————————————————————————");

    // find the reference object which should be the first element of the desired
    // sublist
    Element fromIncluding = elements.stream()
            .filter(element -> element.getAbbreviation().equals("MNO")).findFirst()
            .get();
    Element toIncluding = elements.stream()
            .filter(element -> element.getAbbreviation().equals("YZ1")).findFirst()
            .get();

    List<Element> mnoToYz1 = elements.stream()
            .filter(element ->
                (element.getCreationTime().isAfter(fromIncluding.getCreationTime())
                    && element.getCreationTime().isBefore(toIncluding.getCreationTime()))
                || element.getCreationTime().isEqual(fromIncluding.getCreationTime())
                || element.getCreationTime().isEqual(toIncluding.getCreationTime()))
            .collect(Collectors.toList());

    mnoToYz1.forEach(element -> System.out.println(element.toString()));
}
또한 :

입력리스트가 정렬되어있는 경우, 다른 방법으로는 얻을 수 있습니다 subList와 같은 예에서 객체 비교 대신 범위를 사용하는 것입니다 :

int fromIncluding = IntStream.range(0, elements.size())
    .filter(i -> elements.get(i).getAbbreviation().equals("MNO"))
    .findFirst().orElse(0);
int toIncluding = IntStream.range(fromIncluding, elements.size())
    .filter(i -> elements.get(i).getAbbreviation().equals("YZ1"))
    .findFirst().orElse(elements.size() - 1);

List<Element> mnoToYz1 = elements.subList(fromIncluding, toIncluding+1);

추천

출처http://43.154.161.224:23101/article/api/json?id=211215&siteId=1