简体   繁体   English

如何基于Java中的公共属性合并两个排序的对象列表

[英]How do I merge two sorted object lists based on common attribute in Java

I have two object lists both with a common attribute called timestamp and both are sorted by timestamp. 我有两个对象列表,它们都有一个称为时间戳的通用属性,并且都按时间戳排序。

I want to broadcast these objects one by one based on the timestamp, example if first object of 1st list has timestamp < first object of 2nd list, broadcast first object of the 1st list and then compare second object of the 1st list with the first object of the 2nd list. 我想根据时间戳逐个广播这些对象,例如,如果第一个列表的第一个对象的时间戳<第二个列表的第一个对象,广播第一个列表的第一个对象,然后将第一个列表的第二个对象与第一个对象进行比较第二个列表。

I am a newbie in java. 我是Java的新手。 This is what I have come up with: 这是我想出的:

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

I know my logic is incorrect because for the first item in the Iterators, xIterator.previous and yIterator.previous will point to nothing. 我知道我的逻辑是不正确的,因为对于Iterators中的第一项,xIterator.previous和yIterator.previous将什么都没有指向。 I can't seem to find the correct solution for this problem statement. 我似乎找不到此问题陈述的正确解决方案。 Please help. 请帮忙。

Use indexes instead of iterator. 使用索引而不是迭代器。 You can also use methods to prevent code redundancy 您还可以使用方法来防止代码冗余

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 : 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 : dealWithLeftovers

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

A simple but easy to implement solution: 一个简单但易于实现的解决方案:

  • create a list that simply contains all objects from both lists 创建一个仅包含两个列表中所有对象的列表
  • create a Comparator that knows how to extract timestamps from both different classes - to then compare them 创建一个知道如何从两个不同的类中提取时间戳的比较器-然后比较它们
  • use Collections .sort() to sort the merged list using that comparator 使用Collections .sort()使用该比较器对合并列表进行排序

That's it. 而已。 Now you loop the sorted list to broadcast objects in order. 现在,循环排序列表以按顺序广播对象。

If you want to merge two lists with Sorting with one of the fields, the below example may help u. 如果要将两个列表与“其中的一个字段进行排序”合并,以下示例可能会对您有所帮助。 Using Java8 Streams 使用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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM