在Java中表示大量对象移动的有效方式

时间:2015-02-07 01:14:41

标签: java performance set

有盒子和物品。一个物体留在一个盒子里。 box和object都有一个唯一的索引,每个对象都有一个权重。

我需要创建一个获取大量订单(> 1百万)的方法,您可以在其中查看应该使用出发和目的地框索引移动多少权重,然后返回移动对象集及其目的地。

如果没有性能的想法,它实现起来非常简单易行。 (下面,框索引的类型为Long,对象为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插入或删除元素效率不高。什么是更有效的方式?

1 个答案:

答案 0 :(得分:1)

您是否可以根据对象简单地记录最终目的地,即

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不同 - 这是正确的事情。)

如果您的对象在框之间移动很多,并且可能效率较低,以防它们通常只被移动一次,这将更有效。

我建议尝试一下,将代码与calculateMovingObjectSet一起发布在CR上,这更适合此类问题。