Reputation: 1869
I am looking for a way to retrieve object from hashSet in Java. I did iteration over its elements like this:
for (Customer remainingNode : availableNodes) {
remainingNode.setMarginalGain(calculateMarginalGain(
remainingNode, seedSet, network, availableNodes,
churnNet));
}
Unfortunately due to concurrent modification Exception I have to change that to something like this:
for(int i=0;i<numberofRemainingNodes;i++){
Customer remainingNode=availableNodes.get(i);
remainingNode.setMarginalGain(calculateMarginalGain(
remainingNode, seedSet, network, availableNodes,
churnNet));
numberofRemainingNodes=availableNodes.size();
}
But I can not do that because there is not any get(index) method for Java hashSet. Would you please help me to handle this situation?
P.S: I used HashSet because of I want to handle the union and intersection situation and I did not want to add duplicate element to that. Please consider that this part of my program should be run millions of times so a little extra latency could be expensive for whole program.
FYI:
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;
}
Upvotes: 0
Views: 451
Reputation: 5723
The problem in your code is that you change the structure of your HashSet during the iteration It is within the calculateMarginalGain() method, in this line:
tmpAvailableNodes.removeAll(NeighborOfChurn);
Think twice whether this is really right! If yes, then you can work easily around the problem by making you a copy of the set for the iteration first. E.g.:
Set<Customer> copy = new HashSet<Customer>;
copy.addAll(availableNodes);
for (Customer : copy) {
....
}
Actually tmpAvailableNodes and availableNodes are the identical set. Maybe you can improve here in general.
Upvotes: 1
Reputation: 30528
You have to use an Iterator
:
Iterator<Customer> custIter = availableNodes.iterator();
while(custIter.hasNext()) {
Customer customer = custIter.next();
// do your work here
}
Using this you won't get ConcurrentModificationException
. It is not clear why you get it though. If you are tampering with the HashSet
from multiple Thread
s consider using a concurrent data structure instead.
If you modify availableNodes
in setMarginalGain
you will still get the exception though.
Upvotes: 1