0
    for(int i=0; i<words.size(); i++){
        for(int j=0; j<Final.size(); j++){
        if(words.get(i)==Final.get(j)){
            temp=times.get(j);
            temp=temp+1;
            times.set(j, temp);         
        }
        else{
            Final.add(words.get(i));
            times.add(1);
        }   
        }

}

I want to create two ArrayLists; times(integers) and Final(String). The ArrayList "words" includes words of a string and some words are shown multiple times. What Im trying to do is add every word(but just once) of the "words" to the "Final", and add th number(how many times this word appears on the "words") to the "times" . Is something wrong? Because I get OutOfMemoryError: Java heap space

4
  • 1
    I would use a Map<String, Integer> or Map<String, int[]> as this will be significantly more efficient in terms of CPU, not sure it will help with memory though. I suggest you try a memory profiler to see what is using so much memory. Commented May 14, 2014 at 15:20
  • I think your inner loop never terminates because you keep increasing the size of Final, so your termination criteria is never met and ultimately you run out of heap space. Commented May 14, 2014 at 15:23
  • @Ralf Final size increases onli if the word is already in it. When The loop starts it has some certain size Commented May 14, 2014 at 15:29
  • 1
    @Ralf is almost correct. Your inner for loop states: For every word that is not equal to my word in Final, add my word to the end of Final. This is exponential growth (which devours your memory). The logic is completely wrong, try running it with an empty Final to start with, you won't get a dictionary at the end, only empty lists. Commented May 14, 2014 at 15:36

4 Answers 4

1

I also think using a Hashmap is the best solution.

In your code, there is an error, maybe your problem is here. Replace the following :

        if(words.get(i)==Final.get(j)){

By :

        if(words.get(i).equals(Final.get(j))){
Sign up to request clarification or add additional context in comments.

Comments

1

you don't require two arrays to find out word and its count. you can get this detail after using hashmap. this hashmap contains key as your word and value will be its count. like one hashmap

Map<String, Integer> words = new HashMap<String, Integer>();

and then you can use this map by following way

        try {
        //getting content from file.
        Scanner inputFile = new Scanner(new File("d:\\test.txt"));
                    //reading line by line
        while (inputFile.hasNextLine()) {
            // SringTokenize is automatically divide the string with space.

            StringTokenizer tokenizer = new StringTokenizer(
                    inputFile.nextLine());
            while (tokenizer.hasMoreTokens()) {
                String word = tokenizer.nextToken();
                // If the HashMap already contains the key, increment the
                // value
                if (words.containsKey(word)) {
                    words.put(word, words.get(word) + 1);
                }
                // Otherwise, set the value to 1
                else {
                    words.put(word, 1);
                }
            }

        }

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }// Loop through the HashMap and print the results
    for (Entry<String, Integer> entry : words.entrySet()) {
        String key = entry.getKey();
        Integer value = entry.getValue();

        System.out.println("Word"+key + ": its occurance " + value);

Comments

0

If you are going to run out of memory it would be trying to read all the words into a collection. I suggest you not do this and instead count the words as you get them.

e.g.

Map<String, Integer> freq = new HashMap<>();
try(BufferedReader br = new BufferedReader(new FileReader(filename))) {
    for(String line; (line = br.readLine()) != null; ) {
         for(String word : line.trim().split("\\s+")) {
              Integer count = freq.get(word);
              freq.put(word, count == null ? 1 : 1 + count);
         }
    }
}

Comments

0

try this example.

String[] words = {"asdf","zvcxc", "asdf", "zxc","zxc", "zxc"};
        Map<String, Integer> result = new HashMap<String, Integer>();
        for (String word : words) {
            if (!result.containsKey(word)) {
                result.put(word, 1);
            } else {
                result.put(word, result.get(word) + 1);
            }
        }
        //print result
        for (Map.Entry<String, Integer> entry : result.entrySet()) {
            System.out.println(String.format("%s -- %s times", entry.getKey(), entry.getValue()));
        }

Output:

zvcxc -- 1 times

zxc -- 3 times

asdf -- 2 times

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.