如何从java hashSet中检索对象

时间:2014-03-11 17:13:52

标签: java performance collections hashset

我正在寻找一种从Java中的hashSet中检索对象的方法。我对它的元素进行了迭代:

for (Customer remainingNode : availableNodes) {
remainingNode.setMarginalGain(calculateMarginalGain(
                    remainingNode, seedSet, network, availableNodes,
                    churnNet));
}

不幸的是,由于并发修改异常,我必须将其更改为:

for(int i=0;i<numberofRemainingNodes;i++){
Customer remainingNode=availableNodes.get(i);
remainingNode.setMarginalGain(calculateMarginalGain(
                        remainingNode, seedSet, network, availableNodes,
                        churnNet));
numberofRemainingNodes=availableNodes.size();
}

但我不能这样做,因为Java hashSet没有任何get(index)方法。你能帮我解决这个问题吗?

P.S:我使用HashSet是因为我想处理并集和交集情况,我不想添加重复元素。请考虑我的程序的这一部分应运行数百万次,因此整个程序的额外延迟可能会非常昂贵。

供参考:

private int calculateMarginalGain(Customer remainingNode,
            HashSet<Customer> seedSet,
            DirectedSparseGraph<Customer, Transaction> net,
            Set<Customer> availableNodes, HashSet<Customer> churnNetwork) {
        // Marginal gain for short-term campaign
        HashSet<Customer> tmp = new HashSet<Customer>(); // seedset U
                                                            // {remainingNode}
        tmp.add(remainingNode);
        Set<Customer> tmpAvailableNodes = availableNodes;
        HashSet<Customer> NeighborOfChurn = getNeighbors(churnNetwork, net);
        // sigma function for calculating the expected number of influenced
        // customers- seedSettmp=seedset U {u}
        tmpAvailableNodes.removeAll(NeighborOfChurn);
        Set<Customer> influencedNet = getNeighbors(tmp, net);
        tmpAvailableNodes.retainAll(influencedNet);
        return tmpAvailableNodes.size();
    }

private HashSet<Customer> getNeighbors(HashSet<Customer> churnNetwork,
        DirectedSparseGraph<Customer, Transaction> net) {
    HashSet<Customer> churnNeighbors = churnNetwork;
    Collection<Customer> neighbors = new HashSet<Customer>();
    for (Customer node : churnNetwork) {
        neighbors = net.getNeighbors(node);
        for (Customer neighbor : neighbors) {
            churnNeighbors.add(neighbor);
        }
    }
    return churnNeighbors;
}

2 个答案:

答案 0 :(得分:1)

您必须使用Iterator

Iterator<Customer> custIter = availableNodes.iterator();
while(custIter.hasNext()) {
    Customer customer = custIter.next();
    // do your work here
}

使用此功能,您无法获得ConcurrentModificationException。目前尚不清楚为什么你会这样做。如果您正在篡改多个HashSet中的Thread,请考虑使用并发数据结构。

如果你修改availableNodes中的setMarginalGain,你仍会得到例外。

答案 1 :(得分:1)

您的代码中的问题是您在迭代期间更改了HashSet的结构它位于calculateMarginalGain()方法中,在此行中:

tmpAvailableNodes.removeAll(NeighborOfChurn);

三思这是否真的是对的!如果是,那么您可以通过首先制作迭代集的副本来轻松解决问题。 E.g:

Set<Customer> copy = new HashSet<Customer>;
copy.addAll(availableNodes);
for (Customer : copy) {
  ....
}

实际上tmpAvailableNodes和availableNodes是相同的集合。也许你可以在这里改进。