-2

When I wrote this piece of code due to the pnValue.clear(); the output I was getting was null values for the keys. So I read somewhere that adding values of one map to the other is a mere reference to the original map and one has to use the clone() method to ensure the two maps are separate. Now the issue I am facing after cloning my map is that if I have multiple values for a particular key then they are being over written. E.g. The output I am expecting from processing a goldSentence is:

{PERSON = [James Fisher],ORGANIZATION=[American League, Chicago Bulls]}

but what I get is:

{PERSON = [James Fisher],ORGANIZATION=[Chicago Bulls]}

I wonder where I am going wrong considering I am declaring my values as a Vector<String>

for(WSDSentence goldSentence : goldSentences)
                {   
                    for (WSDElement word : goldSentence.getWsdElements()){
                        if (word.getPN()!=null){
                            if (word.getPN().equals("group")){
                                String newPNTag = word.getPN().replace("group", "organization");
                                pnValue.add(word.getToken().replaceAll("_", " "));
                                newPNValue = (Vector<String>) pnValue.clone();
                                annotationMap.put(newPNTag.toUpperCase(),newPNValue);

                            }


                            else{

                                pnValue.add(word.getToken().replaceAll("_", " "));
                                newPNValue = (Vector<String>) pnValue.clone();
                                annotationMap.put(word.getPN().toUpperCase(),newPNValue);

                            }

                        }

                        sentenceAnnotationMap = (LinkedHashMap<String, Vector<String>>) annotationMap.clone();
                        pnValue.clear();
                    }

EDITED CODE Replaced Vector with List and removed cloning. However this still doesn't solve my problem. This takes me back to square one where my output is : {PERSON=[], ORGANIZATION=[]}

for(WSDSentence goldSentence : goldSentences)
        {   
            for (WSDElement word : goldSentence.getWsdElements()){
                if (word.getPN()!=null){
                    if (word.getPN().equals("group")){
                        String newPNTag = word.getPN().replace("group", "organization");
                        pnValue.add(word.getToken().replaceAll("_", " "));
                        newPNValue = (List<String>) pnValue;
                        annotationMap.put(newPNTag.toUpperCase(),newPNValue);

                    }


                    else{

                        pnValue.add(word.getToken().replaceAll("_", " "));
                        newPNValue =  pnValue;
                        annotationMap.put(word.getPN().toUpperCase(),newPNValue);

                    }

                }

                sentenceAnnotationMap =  annotationMap;

            }
            pnValue.clear();
serendipity
  • 852
  • 13
  • 32
  • You keep calling `pnValue.clear()`. You'll never get more than 1 item in there. – shmosel Feb 12 '17 at 11:50
  • Why are you cloning after to alter the Vector, usually you only take a copy before you modify or it's probably pointless. Also I suggest using a collection from after 1997 e.g. ArrayList. – Peter Lawrey Feb 12 '17 at 11:54
  • If I don't call pnValue.clear() the output I get is {PERSON = [James Fisher,American League, Chicago Bulls],ORGANIZATION=[James Fisher,American League, Chicago Bulls]} – serendipity Feb 12 '17 at 11:54
  • @PeterLawrey I have never used clone() before. How do I edit my code to use it correctly? – serendipity Feb 12 '17 at 11:55
  • @serendipity usually the best way to use `close()` it is to not use it at all. – Peter Lawrey Feb 12 '17 at 12:00
  • @PeterLawrey That doesn't help me. Could you mention any additions I could make to solve this problem? – serendipity Feb 12 '17 at 12:11
  • @serendipity remove clone (which you have), only use a List e.g. ArrayList, you don't need to `put` a key/value which is already in the map. Use the debugger to help determine where the code isn't doing what you expect. – Peter Lawrey Feb 12 '17 at 12:13
  • Also make sure you are not adding the same *reference* to the map multiple time unless you expect it to be the same value. Adding a reference doesn't copy the object referenced. – Peter Lawrey Feb 12 '17 at 12:15

1 Answers1

0

You're trying a bunch of stuff without really thinking through the logic behind it. There's no need to clear or clone anything, you just need to manage separate lists for separate keys. Here's the basic process for each new value:

  • If the map contains our key, get the list and add our value
  • Otherwise, create a new list, add our value, and add the list to the map

You've left out most of your variable declarations, so I won't try to show you the exact solution, but here's the general formula:

List<String> list = map.get(key);  // try to get the list
if (list == null) {                // list doesn't exist?
    list = new ArrayList<>();      // create an empty list
    map.put(key, list);            // insert it into the map
}
list.add(value);                   // update the list
shmosel
  • 49,289
  • 6
  • 73
  • 138