表示 Java 中大量对象移动的有效方法
Efficient way to represent numerous object move in Java
有盒子和物体。一个对象留在一个盒子里。盒子和物体都有一个唯一的索引,每个物体都有一个权重。
我需要创建一个方法来获取大量订单(> 100 万),您可以在其中看到应该使用出发地和目的地框索引移动多少重量,然后 returns 移动对象集及其目的地。
无需性能思考,非常清晰且易于实现。 (下面为了说明,box index的类型是Long,object是Integer)
public static void main(String[] args) {
Map<Long, Set<Integer>> objectsInBox = new HashMap<>();
objectsInBox.put(1l, new HashSet<>(Arrays.asList(1,2,3)));
objectsInBox.put(2l, new HashSet<>(Arrays.asList(4,5,6)));
// .... a lot of objects
Map<Integer, Double> weightsOfObject = new HashMap<>();
weightsOfObject.put(1, 99.9);
weightsOfObject.put(2, 23.4);
// ....
List<Map<Pair<Long, Long>, Double>> moveOrderList = receiveOrderList();
getFinalDestinationOfMovingObject(moveOrderList);
}
public static Map<Long, Set<Integer>> getFinalDestinationOfMovingObject(
List<Map<Pair<Long, Long>, Double>> moveOrderList){
Map<Long, Set<Integer>> finalDestinationOfObjects = new HashMap<>();
for(Map<Pair<Long, Long>, Double> moveOrder : moveOrderList){
// Convert moving amount into object move is not trivial, but given somewhere.
Map<Integer, Pair<Long,Long>> movingObjects = calculateMovingObjectSet(moveOrder);
for(Map.Entry<Integer, Pair<Long,Long>> movingObject : movingObjects.entrySet()) {
int movingObjectIndex = movingObject.getKey();
long departureIndex = movingObject.getValue().getFirst();
long destinationIndex = movingObject.getValue().getSecond();
if(!finalDestinationOfObjects.containsKey(destinationIndex)){
finalDestinationOfObjects.put(departureIndex, new HashSet<Integer>(Arrays.asList(movingObjectIndex)));
}else{
finalDestinationOfObjects.get(departureIndex).add(movingObjectIndex);
}
if(!finalDestinationOfObjects.containsKey(departureIndex)){
// We need just final destination. Remove past object state.
finalDestinationOfObjects.get(departureIndex).remove(movingObjectIndex);
}
}
}
return finalDestinationOfObjects;
}
当移动顺序包含大量元素时,需要花费大量时间。我猜这是因为从 HasSet 插入或删除元素效率不高。什么方法更有效?
能不能简单的根据对象来记录最终的目的地,即
finalDestination.put(movingObjectIndex, destinationIndex);
而不是所有复杂的逻辑?这处理了先前目的地存在和不存在的情况。
如果你真的需要finalDestinationOfObjects
,你可以在最后创建它,比如
Multimap<Long, Integer> finalDestinationOfObjects = HashMultimap.create();
for (val e : finalDestination.entrySet()) {
finalDestinationOfObjects.put(e.getValue(), e.getKey());
}
其中 Multimap
来自 Guava(您不需要它,但是 - 与嵌套的 Map
不同 - 它是正确的)。
如果您的对象在盒子之间移动很多,这会更有效率,如果它们通常只移动一次,效率可能会更低。
我建议试一试 post 代码和 CR 上的 calculateMovingObjectSet
,更适合此类问题。
有盒子和物体。一个对象留在一个盒子里。盒子和物体都有一个唯一的索引,每个物体都有一个权重。
我需要创建一个方法来获取大量订单(> 100 万),您可以在其中看到应该使用出发地和目的地框索引移动多少重量,然后 returns 移动对象集及其目的地。
无需性能思考,非常清晰且易于实现。 (下面为了说明,box index的类型是Long,object是Integer)
public static void main(String[] args) {
Map<Long, Set<Integer>> objectsInBox = new HashMap<>();
objectsInBox.put(1l, new HashSet<>(Arrays.asList(1,2,3)));
objectsInBox.put(2l, new HashSet<>(Arrays.asList(4,5,6)));
// .... a lot of objects
Map<Integer, Double> weightsOfObject = new HashMap<>();
weightsOfObject.put(1, 99.9);
weightsOfObject.put(2, 23.4);
// ....
List<Map<Pair<Long, Long>, Double>> moveOrderList = receiveOrderList();
getFinalDestinationOfMovingObject(moveOrderList);
}
public static Map<Long, Set<Integer>> getFinalDestinationOfMovingObject(
List<Map<Pair<Long, Long>, Double>> moveOrderList){
Map<Long, Set<Integer>> finalDestinationOfObjects = new HashMap<>();
for(Map<Pair<Long, Long>, Double> moveOrder : moveOrderList){
// Convert moving amount into object move is not trivial, but given somewhere.
Map<Integer, Pair<Long,Long>> movingObjects = calculateMovingObjectSet(moveOrder);
for(Map.Entry<Integer, Pair<Long,Long>> movingObject : movingObjects.entrySet()) {
int movingObjectIndex = movingObject.getKey();
long departureIndex = movingObject.getValue().getFirst();
long destinationIndex = movingObject.getValue().getSecond();
if(!finalDestinationOfObjects.containsKey(destinationIndex)){
finalDestinationOfObjects.put(departureIndex, new HashSet<Integer>(Arrays.asList(movingObjectIndex)));
}else{
finalDestinationOfObjects.get(departureIndex).add(movingObjectIndex);
}
if(!finalDestinationOfObjects.containsKey(departureIndex)){
// We need just final destination. Remove past object state.
finalDestinationOfObjects.get(departureIndex).remove(movingObjectIndex);
}
}
}
return finalDestinationOfObjects;
}
当移动顺序包含大量元素时,需要花费大量时间。我猜这是因为从 HasSet 插入或删除元素效率不高。什么方法更有效?
能不能简单的根据对象来记录最终的目的地,即
finalDestination.put(movingObjectIndex, destinationIndex);
而不是所有复杂的逻辑?这处理了先前目的地存在和不存在的情况。
如果你真的需要finalDestinationOfObjects
,你可以在最后创建它,比如
Multimap<Long, Integer> finalDestinationOfObjects = HashMultimap.create();
for (val e : finalDestination.entrySet()) {
finalDestinationOfObjects.put(e.getValue(), e.getKey());
}
其中 Multimap
来自 Guava(您不需要它,但是 - 与嵌套的 Map
不同 - 它是正确的)。
如果您的对象在盒子之间移动很多,这会更有效率,如果它们通常只移动一次,效率可能会更低。
我建议试一试 post 代码和 CR 上的 calculateMovingObjectSet
,更适合此类问题。