我有一个List<MyObject>,有三个属性:
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;
}
}(我知道.弦伤眼睛)。这是我正在研究的一个样本数据:
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我要做的是用流将所有对象设置为active = 0,但最近的对象除外,我想保持它的活动状态。
我被困在这里了,我无法匹配正确的方法:
myList.stream()
.sorted(Comparator.comparing(MyObject::getDate))
//what now?
;预期产出应是:
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谢谢
发布于 2018-10-11 12:21:31
编辑:这里显示的方法可能被看作是对Stream.map操作的滥用,尽管在实践中它总是有效的(在最初版本的post末尾有最后注释的警告)。
请参阅增编,以便采取更清洁的办法。
没有必要进行任何排序(这是一个O(NlogN)操作),而您所要做的就是查找带有最大日期的元素。
您可以流MyObject元素的列表,禁用所有元素,然后找到带有最大日期的元素,并最终激活它:
myList.stream()
.map(myObject -> { myObject.setActive("0"); return myObject; })
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(myObject -> myObject.setActive("1"));如果MyObject类有fluent方法来设置active属性,那么这段代码读起来要好得多:
public MyObject activated() {
active = "1";
return this;
}
public MyObject deactivated() {
active = "0";
return this;
}现在解决办法将是:
myList.stream()
.map(MyObject::deactivated)
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(MyObject::activated);注意:如果流的源按排序报告自身,则该方法可能无法工作。当你使用一个列表时,这是不会发生的。
增编:
正如注释中所讨论的,最干净的方法是将所有元素设置为非活动元素,然后查找带有最大日期的元素,并将其设置为active:
myList.forEach(myObject -> myObject.setActive("0"));
myList.stream()
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(myObject -> myObject.setActive("1"));或者使用fluent方法:
myList.forEach(MyObject::deactivated);
myList.stream()
.max(Comparator.comparing(MyObject::getDate))
.ifPresent(MyObject::activated);当然,这种方法需要2次传递列表,但它清楚地显示了开发人员的意图,并且不滥用流API。
最后一个片段的变体可能是:
myList.forEach(MyObject::deactivated);
if (!myList.isEmpty())
Collections.max(myList, Comparator.comparing(MyObject::getDate))
.activated();发布于 2018-10-11 10:44:08
似乎您首先需要按相反的顺序排序,以便您感兴趣的元素成为第一个:
myList.stream()
.sorted(Comparator.comparing(MyObject::getDate, Comparator.reverseOrder()))
.skip(1)
.forEach(x -> x.setActive("0"))然后跳过它,将其他的设置为0。
发布于 2018-10-11 11:17:52
不需要sort.just通过比较date属性来查找max(最近)对象。
MyObject recent = Collections.max(list,Comparator.comparing(MyObject::getDate));
list.stream().filter(myObject -> !myObject.equals(recent))
.forEach(myObject -> myObject.setActive("0"));https://stackoverflow.com/questions/52757940
复制相似问题