4

I want to rank in java an ArrayList<String> with the number of times that the String appears. Like this: if I have an

ArrayList<String>= [French, English, German, French, French, Belgium, English, Belgium]

I count the number that "French", "English", "Belgium",etc. appear. So French appear 3 times, English 2 times, Belgium 2 times, German one times. Then I want to rank the ArrayList<String> in function of the number.

The result will be:

French 3
English 2 
Belgium 2
German 1

How I can do this? How to associate an integer and a String?

2

3 Answers 3

6

Don't reinvent the wheel and use the frequency method of the Collections class:

public static int frequency(Collection<?> c, Object o)

Returns the number of elements in the specified collection equal to the specified object. More formally, returns the number of elements e in the collection such that (o == null ? e == null : o.equals(e)).

If you need to count the occurrences for all elements, use a Map and loop cleverly :) Or put your list in a Set and loop on each element of the set with the frequency method above. HTH

EDIT / Java 8: If you fancy a more functional, Java 8 one-liner solution with lambdas, try:

Map<String, Long> occurrences = 
  list.stream().collect(Collectors.groupingBy(w -> w, Collectors.counting()));

And then sort the map by value.

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

5 Comments

I wouldn't upvote for the frequency comment, since it still requires that the coder iterate over the List and store/associate the values somehow. But +1 for sick Java 8 skills. :)
I don't understand your answer... When I try .stream() on my list this method doesn't exist...
@momo70 Upgrade to Java 8 and enjoy functional interfaces! is there anything else that you don't understand?
I found a solution here But @okiharaherbst what is w -> w?
@momo70,w -> w is called a lambda expression, and has been introduced to Java in its 8th release to bring some functional programming constructs to the language. Have a look at docs.oracle.com/javase/tutorial/java/javaOO/… and oracle.com/webfolder/technetwork/tutorials/obe/java/… if you're interested and need a primer on the topic. HTH.
2

Any time you need to associate data, you should be thinking Map all the way. HashMap is the basic class used for this. So you can iterate over your list and create your associations in a Map<String, Integer>.

List<String> stuff = new ArrayList<String>();
// ...populate it

Map<String, Integer> map = new HashMap<String, Integer>();    
for(String string : stuff) {
    if(map.containsKey(string)) {
        map.put(string, map.get(string) + 1);
    }
    else {
        map.put(string, 1);
    }
}

Check out the full HashMap API here.

3 Comments

Thank you, that's what I was looking for. But how to rank the map?
@user3590882 Glad it helped you. :) As far as ordering the HashMap, you really don't, usually. A HashMap is fundamentally unordered. If you want to sort based on the key, you can use a TreeMap, but if you want to sort of the value, as I suspect, it becomes a bit harder, especially since there can be identical values (whereas the key is unique). You can check out this Q&A for more information.
I did this map=new TreeMap<String,Integer>(map); And I have the map sorted by String, but how to sort it by key value? I tried map=new TreeMap<String,Integer>(map.values); but it's not recognized... PS: How to write a text like a code in this forum?
0

You need to first create a Language class:

public class Language {
  private String name;
  private int count;

  public Language(String name) { this.name = name; this.count = 0; }
  public String getName() { return this.name; }
  public int getCount() { return this.count; }
  public void setCount(int count) { this.count = count; }
}

And then, create a list of languages from the ArrayList:

List<String> languageNames = // your language names
Map<String, Language> map = new HashMap<String, Language>();

for (String languageName : languageNames) {
  Language language = map.get(languageName);
  if (language == null) {
    language = new Language(languageName);
  } else {
    language.setCount(language.getCount() + 1);
  }
  map.put(languageName, language);
}

List<Language> languages = new ArrayList<Language>(map.values());

After that, we sort, and print the languages:

Collections<Language>.sort(languages, new Comparator<Language>() {
  public int compare(Language l1, Language l2) {
    return l1.getCount() - l2.getCount();
  }
});

System.out.println(languages);

3 Comments

How to use this on the code of Jeff Gohlke? Because his code works on my ArrayList and your code is not the same that I need, so I have to adapt your code to mine. But how? Should I take only the third part about Collection?
OP wants to Rank a List<String> with int in Java which roughly translates into using a map. Don't you think that dedicating a whole class to this is a little too stiff?
We can avoid using classes. But, we need to somehow bind language name with its frequency (number of appearance). The Language class is used for this purpose.

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.