首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将最后一个对象保持为活动对象,并按日期停用旧对象。

将最后一个对象保持为活动对象,并按日期停用旧对象。
EN

Stack Overflow用户
提问于 2018-10-11 10:34:53
回答 3查看 94关注 0票数 4

我有一个List<MyObject>,有三个属性:

代码语言:javascript
复制
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;
    }
}

(我知道.弦伤眼睛)。这是我正在研究的一个样本数据:

代码语言:javascript
复制
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,但最近的对象除外,我想保持它的活动状态。

我被困在这里了,我无法匹配正确的方法:

代码语言:javascript
复制
myList.stream()
    .sorted(Comparator.comparing(MyObject::getDate))
    //what now?
;

预期产出应是:

代码语言:javascript
复制
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

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-10-11 12:21:31

编辑:这里显示的方法可能被看作是对Stream.map操作的滥用,尽管在实践中它总是有效的(在最初版本的post末尾有最后注释的警告)。

请参阅增编,以便采取更清洁的办法。

没有必要进行任何排序(这是一个O(NlogN)操作),而您所要做的就是查找带有最大日期的元素。

您可以流MyObject元素的列表,禁用所有元素,然后找到带有最大日期的元素,并最终激活它:

代码语言:javascript
复制
myList.stream()
    .map(myObject -> { myObject.setActive("0"); return myObject; })
    .max(Comparator.comparing(MyObject::getDate))
    .ifPresent(myObject -> myObject.setActive("1"));

如果MyObject类有fluent方法来设置active属性,那么这段代码读起来要好得多:

代码语言:javascript
复制
public MyObject activated() {
    active = "1";
    return this;
}

public MyObject deactivated() {
    active = "0";
    return this;
}

现在解决办法将是:

代码语言:javascript
复制
myList.stream()
    .map(MyObject::deactivated)
    .max(Comparator.comparing(MyObject::getDate))
    .ifPresent(MyObject::activated);

注意:如果流的源按排序报告自身,则该方法可能无法工作。当你使用一个列表时,这是不会发生的。

增编:

正如注释中所讨论的,最干净的方法是将所有元素设置为非活动元素,然后查找带有最大日期的元素,并将其设置为active:

代码语言:javascript
复制
myList.forEach(myObject -> myObject.setActive("0"));
myList.stream()
    .max(Comparator.comparing(MyObject::getDate))
    .ifPresent(myObject -> myObject.setActive("1"));

或者使用fluent方法:

代码语言:javascript
复制
myList.forEach(MyObject::deactivated);
myList.stream()
    .max(Comparator.comparing(MyObject::getDate))
    .ifPresent(MyObject::activated);

当然,这种方法需要2次传递列表,但它清楚地显示了开发人员的意图,并且不滥用流API。

最后一个片段的变体可能是:

代码语言:javascript
复制
myList.forEach(MyObject::deactivated);
if (!myList.isEmpty()) 
        Collections.max(myList, Comparator.comparing(MyObject::getDate))
                .activated();
票数 5
EN

Stack Overflow用户

发布于 2018-10-11 10:44:08

似乎您首先需要按相反的顺序排序,以便您感兴趣的元素成为第一个:

代码语言:javascript
复制
myList.stream()
      .sorted(Comparator.comparing(MyObject::getDate, Comparator.reverseOrder()))
      .skip(1)
      .forEach(x -> x.setActive("0"))

然后跳过它,将其他的设置为0

票数 2
EN

Stack Overflow用户

发布于 2018-10-11 11:17:52

不需要sort.just通过比较date属性来查找max(最近)对象。

代码语言:javascript
复制
MyObject recent = Collections.max(list,Comparator.comparing(MyObject::getDate));
list.stream().filter(myObject -> !myObject.equals(recent))
            .forEach(myObject -> myObject.setActive("0"));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52757940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档