如何使用 Java 中另一个对象的 属性 对对象列表进行排序?
How to sort list of objects with a property of another object in Java?
我有两个列表,其中包含两种不同类型的对象。
- 协议(obj1)
- 传感器(obj2)
协议列表基于 属性(protocolId) 使用 "Collections.sort" 使用比较器进行排序。现在协议和传感器对象都具有相同的 属性,称为 "referenceName"。由于第一个列表(协议)已排序,我希望使用 属性 "referenceName".
以与协议列表相同的顺序对第二个列表(传感器)进行排序
因为比较器只能比较同一个列表中的两个对象。我在比较第一个列表和第二个列表时遇到问题。有人可以帮我吗?
你为什么不拥有一个新的 class 来保存具有特定 referenceName 的协议和传感器并对其进行排序。以下是 class -
的伪代码
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
}
}
您可以做的是创建索引列表
{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) 作为 class 级变量,因此您可以在 Comparator 中访问它而无需将其作为参数传递。如果您有多个协议结构,这将不起作用。
2.实现自己的排序方式:循环遍历Protocol(obj1),找到对应的Sensor(obj2)。如果您按 referenceName 对 Sensor(obj) 进行预排序,并实施二进制搜索而不是完整循环,则可以提高性能。
通过构造函数将您的列表传递给比较器,然后在您的逻辑中使用该列表
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;
}
}
您可以使用 Java 8 个 lambda 在 referenceName
和它在 Protocol
排序列表中的索引之间创建映射:
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
我有两个列表,其中包含两种不同类型的对象。
- 协议(obj1)
- 传感器(obj2)
协议列表基于 属性(protocolId) 使用 "Collections.sort" 使用比较器进行排序。现在协议和传感器对象都具有相同的 属性,称为 "referenceName"。由于第一个列表(协议)已排序,我希望使用 属性 "referenceName".
以与协议列表相同的顺序对第二个列表(传感器)进行排序因为比较器只能比较同一个列表中的两个对象。我在比较第一个列表和第二个列表时遇到问题。有人可以帮我吗?
你为什么不拥有一个新的 class 来保存具有特定 referenceName 的协议和传感器并对其进行排序。以下是 class -
的伪代码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
}
}
您可以做的是创建索引列表
{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) 作为 class 级变量,因此您可以在 Comparator 中访问它而无需将其作为参数传递。如果您有多个协议结构,这将不起作用。 2.实现自己的排序方式:循环遍历Protocol(obj1),找到对应的Sensor(obj2)。如果您按 referenceName 对 Sensor(obj) 进行预排序,并实施二进制搜索而不是完整循环,则可以提高性能。
通过构造函数将您的列表传递给比较器,然后在您的逻辑中使用该列表
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;
}
}
您可以使用 Java 8 个 lambda 在 referenceName
和它在 Protocol
排序列表中的索引之间创建映射:
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