3

I've been trying to make a java program in which a tab delimited csv file is read line by line and the first column (which is a string) is added as a key to a hash map and the second column (integer) is it's value.

In the input file, there are duplicate keys but with different values so I was going to add the value to the existing key to form an ArrayList of values.

I can't figure out the best way of doing this and was wondering if anyone could help?

Thanks

EDIT: sorry guys, heres where i've got to with the code so far: I should add the first column is the value and the second column is the key.

public class WordNet {

    private final HashMap<String, ArrayList<Integer>> words;
    private final static String LEXICAL_UNITS_FILE = "wordnet_data/wn_s.csv";

    public WordNet() throws FileNotFoundException, IOException {

        words = new HashMap<>();
        readLexicalUnitsFile();
    }

    private void readLexicalUnitsFile() throws FileNotFoundException, IOException{

        BufferedReader in = new BufferedReader(new FileReader(LEXICAL_UNITS_FILE));
        String line;

        while ((line = in.readLine()) != null) {
            String columns[] = line.split("\t");
            if (!words.containsKey(columns[1])) {
                words.put(columns[1], new ArrayList<>());
            }

        }
        in.close();

    }
3
  • Sorry, without any code this is too broad a question. You are expected to have attempted a solution before posting. Please visit the help center and also read How to Ask Commented Jul 17, 2016 at 15:21
  • code added guys apologies for the mistake Commented Jul 17, 2016 at 15:32
  • You split on the tabs, but only read the second column... You do know arrays are zero indexed, right? Commented Jul 17, 2016 at 15:37

3 Answers 3

2

You are close

String columns[] = line.split("\t");
if (!words.containsKey(columns[1])) {
    words.put(columns[1], new ArrayList<>());
}

should be

String columns[] = line.split("\t");
String key = columns[0];                // enhance readability of code below
List<Integer> list = words.get(key);    // try to fetch the list
if (list == null)                       // check if the key is defined
{                                       //   if not
    list = new ArrayList<>();           //      create a new list
    words.put(key,list);                //      and add it to the map
}
list.add(new Integer(columns[1]));      // in either case, add the value to the list

In response to the OP's comment/question

... the final line just adds the integer to the list but not to the hashmap, does something need to be added after that?

After the statement

List<Integer> list = words.get(key);

there are two possibilities. If list is non-null, then it is a reference to (not a copy of) the list that is already in the map.

If list is null, then we know the map does not contain the given key. In that case we create a new empty list, set the variable list as a reference to the newly created list, and then add the list to the map for the key.

In either case, when we reach

list.add(new Integer(columns[1]));

the variable list contains a reference to an ArrayList that is already in the map, either the one that was there before, or one we just creatd and added. We just add the value to it.

Sign up to request clarification or add additional context in comments.

4 Comments

Does this actually add the key and value to the hashmap if the list isn't null?
The only way the list is null is if the key didn't exist in the map, in which case s new empty list is added with the key. Then the value is added to the list.
Ok but the final line just adds the integer to the list but not to the hashmap, does something need to be added after that?
See my updated answer. If this solves your problem, please "accept" it by clicking the checkmark. Thus future visitors will know it helped.
0

I should add the first column is the value and the second column is the key.

You could remplace the ArrayList declaration by a List declaration. But it is not very problematic.

Anyway, not tested but the logic should be such as :

    while ((line = in.readLine()) != null) {
      String columns[] = line.split("\t");
      ArrayList<Integer> valueForCurrentLine = words.get(columns[1]);

      // you instantiate and put the arrayList once
      if (valueForCurrentLine==null){
          valueForCurrentLine = new  ArrayList<Integer>();
          words.put(columns[1],valueForCurrentLine);
      }

      valueForCurrentLine.add(columns[0]);

Comments

0

Upvote to Jim Garrison's answer above. Here's a little more... (Yes, you should check/mark his answer as the one that solved it)

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WordNet {

    private final Map<String, List<Integer>> words;
    private final static String LEXICAL_UNITS_FILE = "src/net/bwillard/practice/code/wn_s.csv";

    /**
     * 
     * @throws FileNotFoundException
     * @throws IOException
     */
    public WordNet() throws FileNotFoundException, IOException {
        words = new HashMap<>();
        readLexicalUnitsFile();
    }

    /**
     * 
     * @throws FileNotFoundException
     * @throws IOException
     */
    private void readLexicalUnitsFile() throws FileNotFoundException, IOException {

        BufferedReader in = new BufferedReader(new FileReader(LEXICAL_UNITS_FILE));
        String line;

        while ((line = in.readLine()) != null) {
            String columns[] = line.split("\t");
            String key = columns[0];
            int valueInt;
            List<Integer> valueList;

            try {
                valueInt = Integer.parseInt(columns[1]);
            } catch (NumberFormatException e) {
                System.out.println(e);
                continue;
            }

            if (words.containsKey(key)) {
                valueList = words.get(key);
            } else {
                valueList = new ArrayList<>();
                words.put(key, valueList);
            }

            valueList.add(valueInt);
        }

        in.close();
    }

    //You can test this file by running it as a standalone app....
    public static void main(String[] args) {
        try {
            WordNet wn = new WordNet();
            for (String k : wn.words.keySet()) {
                System.out.println(k + " " + wn.words.get(k));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.