Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.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 stream API获取以某个匹配开始并以另一个匹配结束的子列表?_Java_Java 8_Java Stream - Fatal编程技术网

如何通过Java stream API获取以某个匹配开始并以另一个匹配结束的子列表?

如何通过Java stream API获取以某个匹配开始并以另一个匹配结束的子列表?,java,java-8,java-stream,Java,Java 8,Java Stream,我对流y方法感兴趣,该方法可以从有序的对象列表中获取子列表。子列表应以一个对象开始,该对象匹配与其属性之一相关的给定条件,并应以一个对象结束,该对象匹配不同的条件 比方说,我有以下类元素: import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class Element implements Comparable<Element> { String abbrevi

我对
y方法感兴趣,该方法可以从有序的对象列表中获取子列表。子列表应以一个对象开始,该对象匹配与其属性之一相关的给定条件,并应以一个对象结束,该对象匹配不同的条件

比方说,我有以下类
元素

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) + "]";
    }
}
我需要从(包括)
“MNO”
到(包括)
“YZ1”
的子列表,保持它在源代码列表中的顺序,将
创建时间
放在一边

我知道如何在不使用流的情况下做到这一点(比如查找开始和结束的索引,然后从索引
开始
到索引
结束
),这可能已经足够了,但在某种程度上是过时的,并不能真正满足我使用现代API的欲望

我可以添加使其工作的方法,但它们只是描述问题的另一种形式,而我无法使用单个stream语句来解决这个问题。此外,这些方法在一系列不同的问题中进行了解释,这些问题提出了一种普遍的可能性,而不是针对流API

一般情况下:
有两个条件和一个
列表
,其中一个子列表将被收集,其第一个元素是一个匹配条件1,其最后一个元素是一个匹配条件2,同时这些元素之间的所有元素也被收集,并且顺序保持原样

因此,如果您知道使用单流API语句获得所需子列表的可能性,请将其添加为答案。

同时,我将看看
reduce()
方法,也许这就是谜团的答案

编辑
我找到了一个解决方案,它使用
stream()
调用为我提供了所需的结果,但我需要其中的三个。一个获取与第一个条件匹配的元素,第二个获取与第二个条件匹配的元素,然后一个使用前两个
流()中找到的两个元素的
creationTime
s获取所需子列表:

publicstaticvoidmain(字符串[]args){
列表元素=生成满足元素();
//打印原点一次,后跟人眼的水平分隔符
element.forEach(element->System.out.println(element.toString());
System.out.println(“-------------------------------------”);
//找到应该是所需对象的第一个元素的引用对象
//子列表
Element fromInclude=elements.stream()
.filter(element->element.get缩写().equals(“MNO”)).findFirst()
.get();
Element toIncluding=elements.stream()
.filter(element->element.get缩写().equals(“YZ1”)).findFirst()
.get();
List mnoToYz1=elements.stream()
.过滤器(滤芯->
(element.getCreationTime().isAfter(fromInclude.getCreationTime())
&&元素.getCreationTime().isBefore(包括.getCreationTime())
||元素.getCreationTime().isEqual(fromInclude.getCreationTime())
||元素.getCreationTime().isEqual(包括.getCreationTime())
.collect(Collectors.toList());
mnoToYz1.forEach(element->System.out.println(element.toString());
}

看起来您需要流上的
takeWhile
/
dropWhile
方法。查看库by

如果输入列表是有序的,获取
子列表的另一种方法是使用范围,而不是示例中的对象比较,如下所示:

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);
int fromcluding=IntStream.range(0,elements.size())
.filter(i->elements.get(i).get缩写().equals(“MNO”))
.findFirst().orElse(0);
int-toIncluding=IntStream.range(fromcluding,elements.size())
.filter(i->elements.get(i).get缩写().equals(“YZ1”))
.findFirst().orElse(elements.size()-1);
列表mnoToYz1=元素。子列表(从包含到包含+1);

感谢您建议使用该库,但我真的不想包含比现有库更多的外部库。不管怎样,这是一个有用的答案,可能会在未来的项目中对我有所帮助。@deaar
takeWhile
dropWhile
操作是在Java 9中添加到streams中的。疑问:你真的为过滤时的
缩写设置或
creationTime
持续时间而烦恼吗?我的意思是,如果我简单地将其表述为
List mnotoyz1ss=elements.stream().takeWhile(element->element.getCreationTime().compareTo(fromIncluding)>=0.dropWhile(element->element.getCreationTime().compareTo(toIncluding)@nullpointer我不能/不想使用
takeWhile
方法,这就是为什么它不能解决我的问题。我找到了一种使用
creationTime
的方法,并在中编辑了该方法,但问题仍然是如何使用
缩写
并在流之前不提取这两个元素。我认为使用命令式方法解决它的方法还需要至少两个
while
循环。因此,您当前的解决方案也没有任何问题。除了
|
条件在检查特定的持续时间时看起来不太确定之外。@nullpointer好的,我也这么认为。我可能会自己回答这个问题,我想f我发现了一种可能性。但请记住,这不会像在样本中那样执行持续时间检查。根据我的理解,根据您的问题,这也不是必需的。第二个流可能使用
IntStream.range(fromInclude,elements.size())
。最好的答案是接受的,尽管需要的流比其他流多
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()));
}
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);