为了账号安全,请及时绑定邮箱和手机立即绑定

保持最后一个对象处于活动状态并按日期停用较旧的对象

保持最后一个对象处于活动状态并按日期停用较旧的对象

婷婷同学_ 2021-11-11 16:30:28
我有一个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;    }}(我知道......字符串会伤害眼睛)。这是我正在处理的示例数据:ID  | ACTIVE | DATE500925  1   2017-12-01 11:43:34501145  1   2018-10-11 11:41:14501146  1   2018-10-11 11:42:51501147  1   2018-10-11 11:45:37我想要做的是将所有对象设置为active = 0流,除了最近的 ,我想保持活动状态。我有点卡在这里,我无法匹配正确的方法来做到这一点:myList.stream()    .sorted(Comparator.comparing(MyObject::getDate))    //what now?;预期的输出应该是:ID  | ACTIVE | DATE500925  0   2017-12-01 11:43:34501145  0   2018-10-11 11:41:14501146  0   2018-10-11 11:42:51501147  1   2018-10-11 11:45:37谢谢
查看完整描述

3 回答

?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

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

myList.stream()
      .sorted(Comparator.comparing(MyObject::getDate, Comparator.reverseOrder()))
      .skip(1)
      .forEach(x -> x.setActive("0"))

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


查看完整回答
反对 回复 2021-11-11
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

无需排序。只需通过比较日期属性找到 max( recent ) 对象。


MyObject recent = Collections.max(list,Comparator.comparing(MyObject::getDate));

list.stream().filter(myObject -> !myObject.equals(recent))

            .forEach(myObject -> myObject.setActive("0"));


查看完整回答
反对 回复 2021-11-11
?
三国纷争

TA贡献1804条经验 获得超7个赞

编辑:此处显示的方法可能会被视为对Stream.map操作的滥用,即使在实践中它始终有效(在帖子的初始版本末尾有最后注释的警告)。


请参阅附录以获得更简洁的方法。


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


您可以流式传输MyObject元素列表,停用所有元素,然后找到具有最大日期的元素,最后激活它:


myList.stream()

    .map(myObject -> { myObject.setActive("0"); return myObject; })

    .max(Comparator.comparing(MyObject::getDate))

    .ifPresent(myObject -> myObject.setActive("1"));

如果MyObject该类具有流利的方法来设置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);

注意:如果流的源将自身报告为已排序,则此方法可能不起作用。当您使用列表时,这不会发生。


附录:


正如评论中所讨论的,最干净的方法是将所有元素设置为非活动状态,然后找到具有最大日期的元素并将其设置为活动状态:


myList.forEach(myObject -> myObject.setActive("0"));

myList.stream()

    .max(Comparator.comparing(MyObject::getDate))

    .ifPresent(myObject -> myObject.setActive("1"));

或者使用流畅的方法:


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();


查看完整回答
反对 回复 2021-11-11
  • 3 回答
  • 0 关注
  • 140 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信