【问题标题】:How do I merge two sorted object lists based on common attribute in Javajava - 如何根据Java中的公共属性合并两个排序的对象列表
【发布时间】:2017-12-13 06:21:39
【问题描述】:

我有两个对象列表,它们都有一个称为时间戳的公共属性,并且都按时间戳排序。

我想根据时间戳逐个广播这些对象,例如,如果第一个列表的第一个对象的时间戳

我是java新手。这是我想出的:

 //Merge the 2 object lists based on timestamp
        ListIterator<x> xIterator = list1.listIterator();
        ListIterator<y> yIterator = list2.listIterator();
        while (xIterator.hasNext() && yIterator.hasNext()) {
            if (xIterator.next().timestamp <= yIterator.next().timestamp) {
                Bundle extra = new Bundle();
                extra.putParcelable(LocalBroadcastConstants.ACTION, xIterator.previous());
                MyBroadcastManager.getInstance(getTargetContext()).sendBroadcast(
                        new Intent(LocalBroadcastConstants.ACTION_SEND).putExtras(extra)
                );
                yIterator.previous();
            } else {
                Bundle extra = new Bundle();
                extra.putParcelable(LocalBroadcastConstants.ACTION,
                        yIterator.previous());
                MyBroadcastManager.getInstance(getTargetContext()).sendBroadcast(
                        new Intent(LocalBroadcastConstants.ACTION_SEND).putExtras(extra)
                );
                xIterator.previous();
            }

我知道我的逻辑是不正确的,因为对于迭代器中的第一项,xIterator.previous 和 yIterator.previous 将指向任何内容。我似乎无法为这个问题陈述找到正确的解决方案。请帮忙。

【问题讨论】:

  • 我对 Java 不熟悉。但是,如果这在 python 中,我将使用索引来跟踪和迭代索引,只有当该项目被广播时。上面的代码似乎效率低下,因为您要上下遍历很多次。如果你愿意,我可以发布一个伪代码
  • Unrelated :编写一个辅助方法来进行广播。复制该代码没有意义。相反 - 它使您的代码更难阅读并且更容易插入错误。每当您开始重复代码时 - 将该代码移动到它自己的方法中。
  • 尽管不相关的@GhostCat 提出了一个非常有效的观点。您应该为任何可重用的代码创建一个帮助类成为一种习惯。

标签: java android object merge


【解决方案1】:

如果您想将两个列表与其中一个字段进行排序,下面的示例可能会对您有所帮助。使用 Java8 流

Obj p1 = new Obj();
    p1.setDept("EC");
    p1.setName("Sagar");
    p1.setJoinedDate(new Date(2007, 8, 2));

    Obj p2 = new Obj();
    p2.setDept("EE");
    p2.setName("Rang");
    p2.setJoinedDate(new Date(2007, 8, 3));

    Obj p3 = new Obj();
    p3.setDept("ME");
    p3.setName("Avadh");
    p3.setJoinedDate(new Date(2008, 8, 2));

    Obj p4 = new Obj();
    p4.setDept("IP");
    p4.setName("Pams");
    p4.setJoinedDate(new Date(2007, 8, 1));

    List<Obj> dept1 = new ArrayList<>();
    dept1.add(p1);
    dept1.add(p2);

    List<Obj> dept2 = new ArrayList<>();
    dept2.add(p3);
    dept2.add(p4);
    dept1.addAll(dept2);
    List<Obj> sortedList = dept1.stream().sorted(new Comparator<Obj>() {

        @Override
        public int compare(Obj o1, Obj o2) {
            if(Instant.ofEpochMilli(o1.getJoinedDate().getTime()).atZone(ZoneId.systemDefault())
            .toLocalDateTime().isBefore(Instant.ofEpochMilli(o2.getJoinedDate().getTime()).atZone(ZoneId.systemDefault())
            .toLocalDateTime())){
                return -1;
            }else if(Instant.ofEpochMilli(o1.getJoinedDate().getTime()).atZone(ZoneId.systemDefault())
                    .toLocalDateTime().isAfter(Instant.ofEpochMilli(o2.getJoinedDate().getTime()).atZone(ZoneId.systemDefault())
                            .toLocalDateTime())){
                return 1;
            }
            return 0;
        }
    }).collect(Collectors.toList());

    System.out.println(sortedList);

【讨论】:

    【解决方案2】:

    使用索引而不是迭代器。您还可以使用方法来防止代码冗余

    int xIndex = 0;
    int yIndex = 0;
    
    while (xIndex < list1.size() && yIndex < list2.size()) {
        if (list1[xIndex].timestamp <= list2[yIndex].timestamp) {
            broadcast(list1, xIndex);
            ++xIndex;
        }
        else {
            broadcast(list2, yIndex);
            ++yIndex;
        }
    }
    
    dealWithLeftovers(list1, xIndex);
    dealWithLeftovers(list2, yIndex);
    

    broadcast:

    private void broadcast(List<> list, int index) {
        Bundle extra = new Bundle();
        extra.putParcelable(LocalBroadcastConstants.ACTION, list[index]);
        MyBroadcastManager.getInstance(getTargetContext()).sendBroadcast(
            new Intent(LocalBroadcastConstants.ACTION_SEND).putExtras(extra)
        );
    }
    

    dealWithLeftovers:

    private void dealWithLeftovers(List<> list, int index) {
        for (int i = index; i < list.size() ; ++i) {
            broadcast(list, i);
        }
    }
    

    【讨论】:

    • 您还可以将帮助类合并到您的 dealWithLeftOvers 函数中。
    【解决方案3】:

    一个简单但易于实施的解决方案:

    • 创建一个仅包含两个列表中所有对象的列表
    • 创建一个比较器,它知道如何从两个不同的类中提取时间戳 - 然后比较它们
    • 使用 Collections .sort() 使用该比较器对合并列表进行排序

    就是这样。现在您循环排序列表以按顺序广播对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 2015-09-15
      • 1970-01-01
      • 2020-05-16
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      相关资源
      最近更新 更多