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

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

Collect a stream after an objects attribute exceeds a certain threshold

问题

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

  1. class MaDate {
  2. int temp;
  3. // 其他一些字段
  4. MaDate(int temp){
  5. this.temp = temp;
  6. }
  7. int getTemp(){
  8. return temp;
  9. }
  10. }

以及

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

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

我不能使用 filter

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

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

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

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

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

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

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

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

或者

  1. 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 .

  1. class MaDate {
  2. int temp;
  3. // some other fields
  4. MaDate(int temp){
  5. this.temp = temp;
  6. }
  7. int getTemp(){
  8. return temp;
  9. }
  10. }

And

  1. List&lt;MaDate&gt; myList = new ArrayList&lt;&gt;();
  2. myList.add(new MaDate(3));
  3. myList.add(new MaDate(7));
  4. myList.add(new MaDate(8));
  5. myList.add(new MaDate(4));
  6. myList.add(new MaDate(10));
  7. myList.add(new MaDate(3));
  8. 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

  1. 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

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

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

  1. 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

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

or

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

?

答案1

得分: 3

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

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

示例:

  1. List&lt;MaDate&gt; originalList = ...;
  2. List&lt;MaDate&gt; newList = originalList.stream()
  3. .dropWhile(m -&gt; m.getTemp() &lt; 10)
  4. .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:

  1. List&lt;MaDate&gt; originalList = ...;
  2. List&lt;MaDate&gt; newList = originalList.stream()
  3. .dropWhile(m -&gt; m.getTemp() &lt; 10)
  4. .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:

确定