英文:
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)
因为我需要在达到阈值后获取所有对象,不管在此之后对象具有什么值。
我能否以某种方式组合上述内容以获得我想要的结果,或者编写自己的方法并将其放入 skip
或 filter
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 >= 10
.
class MaDate {
int temp;
// some other fields
MaDate(int temp){
this.temp = temp;
}
int getTemp(){
return temp;
}
}
And
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));
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 -> m.getTemp() >= 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 -> m.getTemp() >= 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<MaDate> originalList = ...;
List<MaDate> newList = originalList.stream()
.dropWhile(m -> m.getTemp() < 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<MaDate> originalList = ...;
List<MaDate> newList = originalList.stream()
.dropWhile(m -> m.getTemp() < 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论