繁体   English   中英

如何在Java中使用另一个对象的属性对对象列表进行排序?

[英]How to sort list of objects with a property of another object in Java?

我有两个列表,其中包含两种不同类型的对象。

  1. 协议(OBJ1)
  2. 传感器(OBJ2)

使用比较器使用“Collections.sort”基于属性(protocolId)对协议列表进行排序。 现在,Protocol和Sensor对象都具有相同的属性,称为“referenceName”。 由于第一个列表(协议)已排序,我希望使用属性“referenceName”按照协议列表的相同顺序对第二个列表(传感器)进行排序。

由于比较器只能比较同一列表中的两个对象。 我将第一个列表与第二个列表进行比较时遇到问题。 有人可以帮帮我吗?

为什么没有一个新的类同时包含具有特定referenceName的Protocol和Sensor并对其进行排序。 以下是该类的伪代码 -

class ProtocolSensorGroup implements Comparable {
  private String referenceName;
  private Protocol protocol;
  private Sensor sensor;

  public boolean compareTo(ProtocolSensorGroup lhs, ProtocolSensorGroup rhs) {
    String pidLhs = lhs.getProtocol().getId();
    String pidRhs = rhs.getProtocol().getId();

    return pidLhs.compareTo(pidRhs); // Or your logic here
  }
}

您可以使用Java 8 lambdas在Protocol排序列表中的referenceName及其索引之间创建映射:

public class Protocol {
    final String referenceName;

    public String getReferenceName() {
        return referenceName;
    }

    // other stuff
}

public class Sensor {
    final String referenceName;

    public String getReferenceName() {
        return referenceName;
    }

    // other stuff
}

final List<Protocol> protocols = getProtocols();
final List<Sensor> sensors = getSensors();

// TODO : sort protocols here

// create a mapping between a referenceName and its index in protocols
final Map<String, Integer> referenceNameIndexesMap = IntStream.range(0, protocols.size()).mapToObj(i -> i)
            .collect(Collectors.toMap(i -> protocols.get(i).getReferenceName(), i -> i));

// sort sensors using this mapping
sensors.sort(Comparator.comparing(s -> referenceNameIndexesMap.get(s.getReferenceName())));

// sensors is now sorted in the same order of referenceName as protocols

您可以做的是创建索引列表

{0, 1, 3 ...} //0 reprssents the first object in both lists and so on

现在使用比较器对此列表进行排序,其中compareTo方法将比较2个整数,它将比较ProtocolList中的等价对象

   @Override
   public int compareTo(Integer o1, Integer o2) {
      //now compare protocolList.get(o1).getProtocolId, protocolList implementation should not be linkedList
   }

现在您已经订购了索引列表,您可以使用有序索引重新填充您使用它的列表,例如传感器列表

List<Sensor> orderedSensorList = new ArrayList<>();
for(int i=0; i< indexesList.size(); i++) {//make sure the implementation of the indexes list is not linked list or the time complexity will be O(n^2)
    orderedSensorList.add(sensorList.get(idexesList.get(i));//sensorList is the unordered sensor list
 }    

我看到两个选项:1。将Protocol(obj1)作为类级别变量,因此您可以在Comparator中访问它而不将其作为参数传递。 如果您有多个Protocol结构,这将不起作用。 2.实现自己的排序方法:循环遍历Protocol(obj1),找到相应的Sensor(obj2)。 如果您通过referenceName对Sensor(obj)进行预排序,并实现二进制搜索而不是完整循环,则可以提高性能。

通过构造函数将列表传递给Comparator,然后使用您的逻辑中的列表

public class MyComparator implements Comparator  {

        private List<Protocol> protocoList;

        public MyComparator(List<Protocol> protocoList ){
            this.protocoList=protocoList;
        }

        @Override
        public int compare(Object o1, Object o2) {
            // Write logic using reference of list pass through constructor.
            return 0;
        }

    }

暂无
暂无

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

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