Lev*_*and 4 java java-8 java-stream
我有一个List<MyObject>,有3个属性:
public class MyObject{
long id;
String active;
java.util.Date date;
public MyObject(long id, String active, Date date) {
this.id = id;
this.active = active;
this.date = date;
}
}
Run Code Online (Sandbox Code Playgroud)
(我知道......弦伤了眼睛).这是我正在研究的样本数据:
ID | ACTIVE | DATE
500925 1 2017-12-01 11:43:34
501145 1 2018-10-11 11:41:14
501146 1 2018-10-11 11:42:51
501147 1 2018-10-11 11:45:37
Run Code Online (Sandbox Code Playgroud)
我要做的是将所有对象设置为active = 0流,除了最近的,我想保持活动状态.
我有点卡在这里,我无法匹配正确的方法:
myList.stream()
.sorted(Comparator.comparing(MyObject::getDate))
//what now?
;
Run Code Online (Sandbox Code Playgroud)
预期产量应为:
ID | ACTIVE | DATE
500925 0 2017-12-01 11:43:34
501145 0 2018-10-11 11:41:14
501146 0 2018-10-11 11:42:51
501147 1 2018-10-11 11:45:37
Run Code Online (Sandbox Code Playgroud)
谢谢
编辑:这里显示的方法可能被视为滥用Stream.map操作,尽管在实践中总会(与最后需要说明的在后的最初版本结束的警告)工作.
有关更清洁的方法,请参阅附录.
O(NlogN)当你所要做的就是找到具有最大日期的元素时,没有必要进行任何排序(这是一个操作).
您可以流式传输MyObject元素列表,停用所有元素,然后找到具有最大日期的元素,最后激活它:
myList.stream()
.map(myObject -> { myObject.setActive("0"); return myObject; })
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(myObject -> myObject.setActive("1"));
Run Code Online (Sandbox Code Playgroud)
如果MyObject类具有设置active属性的流畅方法,则此代码将更好地读取:
public MyObject activated() {
active = "1";
return this;
}
public MyObject deactivated() {
active = "0";
return this;
}
Run Code Online (Sandbox Code Playgroud)
现在解决方案将成为:
myList.stream()
.map(MyObject::deactivated)
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(MyObject::activated);
Run Code Online (Sandbox Code Playgroud)
注意:如果流的源将自身报告为已排序,则此方法可能不起作用.当您使用列表时,这不会发生.
附录:
正如评论中所讨论的,最干净的方法是将所有元素设置为非活动状态,然后找到具有最大日期的元素并将其设置为活动状态:
myList.forEach(myObject -> myObject.setActive("0"));
myList.stream()
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(myObject -> myObject.setActive("1"));
Run Code Online (Sandbox Code Playgroud)
或者使用流利的方法:
myList.forEach(MyObject::deactivated);
myList.stream()
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(MyObject::activated);
Run Code Online (Sandbox Code Playgroud)
当然,这种方法需要在列表上进行2次传递,但它清楚地显示了开发人员的意图,并且不会滥用流API.
最后一个片段的变体可能是:
myList.forEach(MyObject::deactivated);
if (!myList.isEmpty())
Collections.max(myList, Comparator.comparing(MyObject::getDate))
.activated();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
77 次 |
| 最近记录: |