Como obter uma sublista começando com um certo jogo e terminando com um jogo diferente de Java fluxo de API?

deHaar:

Estou interessado em uma streammaneira y para obter uma sub-lista a partir de uma ordenada lista de objetos. O sub-lista deve começar com um objeto que corresponde uma dada condição relativa a um dos seus atributos e deve terminar com um objeto que corresponde uma condição diferente.

Vamos dizer, eu tenho a seguinte classe 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) + "]";
    }
}

Eu recebo uma List<Element>que é requisitada pelo creationTime. Agora eu quero saber se existem elementos entre dois mais específicos apenas em relação à sua abbreviation. Eu sei como filterelementos individuais ou listas de elementos que correspondem a um determinado abbreviationutilizando findFirst()ou findAny()e Collectors.toList(). No entanto, eu só não sei como encontrar um começo sublista com uma certa abbreviatione terminando com outra porque os elementos no meio do (e deve) não corresponder às condições e há duas condições diferentes.

Suponha que eu tenho o seguinte List<Element>(método -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;
}

Eu preciso da sublista a partir de (incluindo) "MNO"a (inclusive) "YZ1"manter a ordem tem na lista de origens, deixando o creationTimelado .

Eu sei como fazer isso sem o uso de correntes (como encontrar índices de início e fim e, em seguida, obter os elementos do índice startpara o índice end), que pode ser suficiente, mas é de algum modo antiquado e não realmente satisfazer minha ambição para a utilização de APIs modernos.

Eu poderia adicionar as maneiras que eu fiz-lhe o trabalho, mas eles seria apenas uma outra forma de descrever o problema que eu não sou capaz de resolver usando um único fluxo-statement. Além disso, essas formas são explicados em uma infinidade de diferentes questões que pedem uma possibilidade geral e não visando API fluxo.

Em geral:
Existem duas condições e List<Element>onde uma sub-lista deve ser recolhido cujo primeiro elemento é a condição de um correspondente 1 e cujo último elemento que a condição de um correspondente 2, enquanto todos os elementos entre os que são coletados, também, e as estadias de ordem como que está na origem.

Então, se você sabe que a possibilidade de obter a sub-lista desejada com uma única instrução fluxo de API, por favor, adicioná-lo como uma resposta.

Vou ter um olhar para o reduce()método, entretanto, talvez essa é a resposta para o mistério ...

EDIT
Eu encontrei uma solução que me dá o resultado desejado usando stream()chamadas, mas eu preciso de três deles. Uma busca que o elemento que coincide com a primeira condição, uma segunda que se encontra o elemento correspondente para a segunda condição e, em seguida, uma que vai buscar a sublista desejada usando as creationTimes dos dois elementos que foram encontrados nas duas primeiras stream()s:

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()));
}
também:

Se a lista de entrada é ordenada, uma outra maneira de obter o subListestaria usando o intervalo em vez da comparação de objetos no seu exemplo como:

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

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=211216&siteId=1
Recomendado
Clasificación