6

I have a HashMap where the key is of type String and the value is of type LinkedList of type String.

So basically, here's what I'm trying to do.

while (contentItr.hasNext()) {
    String word = (String) contentItr.next();
    if (wordIndex.containsKey(word)) {
        LinkedList temp = (LinkedList) w.get(word); //Error occurs here
        temp.addLast(currentUrl);
    } else {
        w.put(word, new LinkedList().add(currentUrl));
    }
}

The first time that I add a key,value pair, I receive no error. However, when I try to retrieve the linked list associated with an existing key, I get the following exception:

java.lang.Boolean cannot be cast to java.util.LinkedList. 

I don't have a possible explanation of why this exception occurs.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
lbj-ub
  • 1,425
  • 2
  • 19
  • 34

2 Answers2

11

Try this instead:

while (contentItr.hasNext()) {
    String word = (String) contentItr.next();
    if (wordIndex.containsKey(word)) {
        LinkedList temp = (LinkedList) w.get(word);
        temp.addLast(currentUrl);
    } else {
        LinkedList temp = new LinkedList();
        temp.add(currentUrl);
        w.put(word, temp);
    }
}

The problem, as you can see, was in the line that adds a new element to the Map - the method add returns a boolean value, and that's what was being added to the Map. The code above fixes the problem and adds what you intended to the Map - a LinkedList.

As an aside note, consider using generic types in your code, in that way errors like this can be prevented. I'll try to guess the types from your code (adjust them if necessary, you get the idea), let's say you have these declarations somewhere in your program:

Map<String, String> wordIndex = new HashMap<String, String>();
Map<String, LinkedList<String>> w = new HashMap<String, LinkedList<String>>();

List<String> content = new ArrayList<String>();
Iterator<String> contentItr = content.iterator();

With that, the piece of code in your question can be safely written, avoiding unnecessary casts and type errors like the one you had:

while (contentItr.hasNext()) {
    String word = contentItr.next();
    if (wordIndex.containsKey(word)) {
        LinkedList<String> temp = w.get(word);
        temp.addLast(currentUrl);
    } else {
        LinkedList<String> temp = new LinkedList<String>();
        temp.add(currentUrl);
        w.put(word, temp);
    }
}

EDIT

As per the comments below - assuming that you actually can replace the LinkedList by an ArrayList (which might be faster for some operations) and that the only LinkedList-specific method you're using is addLast (which is a synonym for add), the above code can be rewritten as follows, in a more Object-Oriented style using interfaces instead of concrete classes for the containers:

Map<String, String> wordIndex = new HashMap<String, String>();
Map<String, List<String>> w = new HashMap<String, List<String>>();

List<String> content = new ArrayList<String>();
Iterator<String> contentItr = content.iterator();

while (contentItr.hasNext()) {
    String word = contentItr.next();
    if (wordIndex.containsKey(word)) {
        List<String> temp = w.get(word);
        temp.add(currentUrl);
    } else {
        List<String> temp = new ArrayList<String>();
        temp.add(currentUrl);
        w.put(word, temp);
    }
}
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Yes, nice, but I like @yshavit's recommendation of strongly typing the `HashMap`. Most container methods benefit nicely from being declared with generic arguments. – Rob I Dec 06 '11 at 04:09
  • I just edited my code to show you an example of how that can be accomplished - adapt it to your actual needs! – Óscar López Dec 06 '11 at 04:17
  • Unless you need any LinkedList-specific methods, I would make it a `Map>` -- not a `Map>`. There are various discussions on SO and elsewhere about coding to interfaces. And btw, if you don't need that LinkedList functionality, consider an `ArrayList` instead. See http://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist – yshavit Dec 06 '11 at 04:21
  • OP is using a `LinkedList`-specific method: `addLast`, so using a `List` is out of the question – Óscar López Dec 06 '11 at 04:22
  • @Óscar López `addLast` is identical to `add`, so if that's the only `LinkedList`-specific method, I would still go with `List`. – yshavit Dec 06 '11 at 04:24
  • @yshavit thanks for your comments, I just edited my answer to take them into account – Óscar López Dec 06 '11 at 04:38
6

List.add returns boolean, which is being autoboxed to Boolean. Your else clause is creating a LinkedList, calling a method on it (add) that returns boolean, and putting the resulting autoboxed Boolean into the map.

Do you know about generics? You should type w as a Map<String,List<String>> instead of just a Map. If you did that, this error would have been caught at compile time.

yshavit
  • 42,327
  • 7
  • 87
  • 124