I am having a problem with this consumer class. When i run the program i get an out of bounds exception with each thread in the pool. I have sysout the list size and it is zero for some reason. Please see my code below. I'ts something to with the list being set but i cant figure it out. Every other part of the program is working and tested just this last part is giving me problems. Any help offered would be greatly appreciated.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Consumer implements Runnable {
private BlockingQueue<Shingle> q;
private int k;
private int[] minHashes;
private Map<Integer, List<Integer>> map = new HashMap<>();
private ExecutorService pool;
public Consumer(BlockingQueue<Shingle> q, int k, int poolSize) {
super();
this.q = q;
this.k = k;
pool = Executors.newFixedThreadPool(poolSize);
init();
}
public void init() {
Random random = new Random();
minHashes = new int[k];
for (int i = 0; i < minHashes.length; i++) {
minHashes[i] = random.nextInt();
}
}
public void run(){
try {
int docCount = 2;
while (docCount > 0) {
Shingle s = q.take();
if (s instanceof Poision) {
docCount--;
} else {
pool.execute( new Runnable() {
public void run() {
for (int i = 0; i < minHashes.length; i++) {
int value = s.getHashCode() ^ minHashes[i]; // ^ - xor(Random generated key)
List<Integer> list = map.get(s.getDocId());
if (list == null) {
list = new ArrayList<Integer>(k);
for (int j = 0; j < list.size(); j++) {
list.set(j , Integer.MAX_VALUE);
}
map.put(s.getDocId(), list);
} else {
if (list.get(i) > value) {
list.set(i, value);
}
}
}
}
});
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The issue is that this line
list = new ArrayList<Integer>(k);
create list with initial capacity equal to k not with size equal to k. So your list has 0 elements and the for loop
for (int j = 0; j < list.size(); j++) {
list.set(j , Integer.MAX_VALUE);
}
doesn't execute any iteration. You then add empty list to the map and because of that list.get(i)
throws exception.
Please change your for loop to
for (int j = 0; j < minHashes.length; j++) {
list.add(Integer.MAX_VALUE);
}
to actually add elements to list.