收集一个对象属性超过某个阈值后的流数据。

huangapple go评论104阅读模式
英文:

Collect a stream after an objects attribute exceeds a certain threshold

问题

假设我有一个包含自定义对象 MaDate 的列表,其中有一个名为 temp 的字段,类型为 int。我想使用流来获取在第一个对象满足某个阈值 MaDate.temp >= 10 后的所有项目。

class MaDate {
    int temp;
    // 其他一些字段
    MaDate(int temp){
       this.temp = temp;
    }
    int getTemp(){
        return temp;
    }
}

以及

List<MaDate> myList = new ArrayList<>();
myList.add(new MaDate(3));
myList.add(new MaDate(7));
myList.add(new MaDate(8));
myList.add(new MaDate(4));
myList.add(new MaDate(10));
myList.add(new MaDate(3));
myList.add(new MaDate(9));

理想情况下,结果列表应该包含最后3个具有 temp 值 [10, 3, 9] 的元素。

我不能使用 filter

myList.stream().filter(m -> m.getTemp() >= 10)...

因为这会消除每个值小于10的对象。我也不能使用 skip

myList.stream().skip(4)...

因为我事先不知道索引。我也不能使用

findFirst(m -> m.getTemp() >= 10)

因为我需要在达到阈值后获取所有对象,不管在此之后对象具有什么值。

我能否以某种方式组合上述内容以获得我想要的结果,或者编写自己的方法并将其放入 skipfilter

myList.stream().skip(**只要阈值未达到**)

或者

myList.stream().filter(**在第一个元素的值大于10后的所有元素**)

英文:

Assume I have a list of custom objects MaDate with a field temp of type int. I want to use streams to get all items after the first hits a certain threshold MaDate.temp &gt;= 10 .

class MaDate {
    int temp;
    // some other fields
    MaDate(int temp){
       this.temp = temp;
    }
    int getTemp(){
        return temp;
    }
}

And

 List&lt;MaDate&gt; myList = new ArrayList&lt;&gt;();
 myList.add(new MaDate(3));
 myList.add(new MaDate(7));
 myList.add(new MaDate(8));
 myList.add(new MaDate(4));
 myList.add(new MaDate(10));
 myList.add(new MaDate(3));
 myList.add(new MaDate(9));

Ideally the result list should contain the last 3 elements having temp values [10,3,9].

I can not use filter

myList.stream().filter(m -&gt; m.getTemp() &gt;= 10)...

because this would eliminate every object with value under 10. And I can not also use skip

myList.stream().skip(4)...

because I do not know the index beforehand. I can not use

findFirst(m -&gt; m.getTemp() &gt;= 10)

because I need all objects after the treshold was reached once regardles which values the objects have after that.

Can I combine those above somehow to get what I want or write my own method to put in skip or filter

 myList.stream().skip(**as long as treshold not met**)

or

 myList.stream().filter(**all elements after first element value above 10**)

?

答案1

得分: 3

如果我正确理解你的问题,那么你可以使用Stream#dropWhile(Predicate)

> 如果此流是有序的,则返回一个流,该流由匹配给定谓词的元素的最长前缀之后剩余的元素组成。否则,如果此流是无序的,则返回一个流,该流由匹配给定谓词的元素的子集之后剩余的元素组成。

示例:

List&lt;MaDate&gt; originalList = ...;
List&lt;MaDate&gt; newList = originalList.stream()
        .dropWhile(m -&gt; m.getTemp() &lt; 10)
        .collect(Collectors.toList());

请注意,dropWhile 在 Java 9 中添加。如果你使用 Java 8,可以参考这个问题的解决方法:通过谓词限制流的大小

英文:

If I understand your question correctly then you can use Stream#dropWhile(Predicate):

>Returns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate. Otherwise returns, if this stream is unordered, a stream consisting of the remaining elements of this stream after dropping a subset of elements that match the given predicate.

Example:

List&lt;MaDate&gt; originalList = ...;
List&lt;MaDate&gt; newList = originalList.stream()
        .dropWhile(m -&gt; m.getTemp() &lt; 10)
        .collect(Collectors.toList());

Note that dropWhile was added in Java 9. This Q&A shows a workaround if you're using Java 8: Limit a stream by a predicate.

huangapple
  • 本文由 发表于 2020年8月14日 06:01:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63403822.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定