代码之家  ›  专栏  ›  技术社区  ›  Leviand

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

  •  4
  • Leviand  · 技术社区  · 6 年前

    我有一个 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 | 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
    

    谢谢

    3 回复  |  直到 6 年前
        1
  •  5
  •   fps    6 年前

    编辑: 这里显示的方法可能被视为滥用 Stream.map 操作,即使在实践中它总是有效的(在文章的初始版本的末尾有最后的注释)。


    O(NlogN) 操作),此时您所要做的就是找到具有最大日期的元素。

    MyObject 元素,停用所有元素,然后找到具有最大日期的元素并最终激活它:

    myList.stream()
        .map(myObject -> { myObject.setActive("0"); return myObject; })
        .max(Comparator.comparing(MyObject::getDate))
        .ifPresent(myObject -> myObject.setActive("1"));
    

    如果 类将有流畅的方法来设置 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"));
    

    或者使用fluent方法:

    myList.forEach(MyObject::deactivated);
    myList.stream()
        .max(Comparator.comparing(MyObject::getDate))
        .ifPresent(MyObject::activated);
    

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

    myList.forEach(MyObject::deactivated);
    if (!myList.isEmpty()) 
            Collections.max(myList, Comparator.comparing(MyObject::getDate))
                    .activated();
    
        2
  •  2
  •   Eugene    6 年前

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

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

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

        3
  •  1
  •   Hadi Jeddizahed    6 年前

    不需要分类。只要找到马克斯( 最近的

    MyObject recent = Collections.max(list,Comparator.comparing(MyObject::getDate));
    list.stream().filter(myObject -> !myObject.equals(recent))
                .forEach(myObject -> myObject.setActive("0"));