1

Intro

First of all I want to start off by saying that I am learning java so if at any point I am doing something that is inefficient or could be done better, please let me know.

What I am trying to do is sort a HashMap alphabetically by key and then return a list of the values in that order. After googling, I found that I could sort a HashMap easily using a SortedSet, but then I run into the problem of how do I get the tree set into an array?

Example

An input like this:

{"apple", "pear", "cherry", "apple", "cherry", "pear", "apple", "banana"}

Should return this:

{3,1,2,2}

My Code (so far)

import java.util.*;

public class SortedFreqs {
    public int[] freqs(String[] data) {
        HashMap<String, Integer> myMap = new HashMap<String, Integer>();
        for (String s: data){
            if (!myMap.containsKey(s)){
                myMap.put(s, 0);
            }
        myMap.put(s, myMap.get(s)+1);
        }
    SortedSet<Integer> values = new TreeSet<Integer>(myMap.values());
    }
}
SpaceShroomies
  • 1,635
  • 2
  • 17
  • 23

3 Answers3

4

SortedSet extends Collection which defines the method toArray:

Integer[] toArray = values.toArray(new Integer[values.size()]);

However, there is one problem which is that the collections use generics and your method is defined as returning a primitive array of int[]. There's no built in way to convert an int[] to an Integer[] so you either need to change your method signature or copy the array yourself:

int[] primitives = new int[toArray.length];
for(int i = 0; i < toArray.length; i++) {

    primitives[i] = toArray[i].intValue();
    // or just    = toArray[i];
    // because intValue is called automagically by the compiler
}

Though, actually, it seems like here you should just be returning the Map. Maybe use TreeMap instead of HashMap if you want to return it sorted alphabetically.

If you really want to do it the way you described in the OP, you'd need to sort the values by their key. The problem being that new TreeSet<Integer>(myMap.values()) sorts the integers numerically. So you'd need to do something like:

Collection<Integer> values = new TreeMap<String, Integer>(myMap).values();
Integer[] toArray = values.toArray(new Integer[values.size()]);

But I'd recommend returning a Map. Because otherwise it's difficult to tell which numbers correspond to which String.

Radiodef
  • 37,180
  • 14
  • 90
  • 125
0

Solved it like this, thanks for the comments and responses. Really helped.

import java.util.*;

public class SortedFreqs {
    public int[] freqs(String[] data) {
        int count = 0;
        TreeMap<String, Integer> myMap = new TreeMap<String, Integer>();
        for (String s: data){
            if (!myMap.containsKey(s)){
                myMap.put(s, 0);
                count++;
            }
        myMap.put(s, myMap.get(s)+1);
        }
    int [] ans = new int [count];
    int c = 0;
    for (String i: myMap.keySet()){
        ans[c] = myMap.get(i);
        c++;
    }
    return ans;
    }
}
SpaceShroomies
  • 1,635
  • 2
  • 17
  • 23
0
public static Integer[] freqs(String[] data) {
    HashMap<String, Integer> myMap = new HashMap<String, Integer>();
    for (String s : data) {
        if (!myMap.containsKey(s)) {
            myMap.put(s, 0);
        }
        myMap.put(s, myMap.get(s) + 1);
    }
    return new TreeMap<String, Integer>(myMap).values().toArray(new Integer[myMap.size()]);
}
卢声远 Shengyuan Lu
  • 31,208
  • 22
  • 85
  • 130