-3

I want to print the count of each word in an ArrayList in alphabetical order. I have implemented the code but for an element "hihi" in the list, I want the count should be 2 instead of 1. How to achieve that?

 {//some code
                 Collections.sort(list);

            System.out.println("Words with the count");
            Map<String, Long> st1=new TreeMap<>();
            for(String k : list){
                st1.put(k,st1.getOrDefault(k, 0L)+1);
            }
            for(String k : st1.keySet()){
            System.out.println(k+": "+st1.get(k));
        }
    //end of class}
  • 1
    Possible duplicate of [How can I sort a List alphabetically?](https://stackoverflow.com/questions/708698/how-can-i-sort-a-list-alphabetically) – Zephyr Jun 17 '19 at 17:58
  • @Zephyr my problem is different. I have already used the sort method. – rahul negi Jun 17 '19 at 18:04
  • 1
    Possible duplicate of [Any implementation of Ordered Set in Java?](https://stackoverflow.com/questions/8712469/any-implementation-of-ordered-set-in-java) – Alessandro Da Rugna Jun 17 '19 at 18:46

2 Answers2

2

Order is not guaranteed in a HashSet by design.

From the docs:

It makes no guarantees as to the iteration order of the set;

If you're wanting to use a Set you need to use a set that guarantees order. LinkedHashSet guarantees insertion order.

Christopher Schneider
  • 3,745
  • 2
  • 24
  • 38
1

Look at using TreeSet over HashSet. TreeSet will order the elements using their natural ordering. You can pass in a Comparator to the constructor of the TreeSet if you would like different sort order.

You should note that your current code is a little inefficient in that it has to iterate through the entire list for every single word to get the frequency count. You would be better off processing the list up front and counting the frequency and storing this in a map. For example:

    Map<String, Long> frequency = new TreeMap<>();
    for (String word : list) {
        frequency.put(word, frequency.getOrDefault(word, 0L) + 1);
    }

    for (String word : frequency.keySet()) {
        System.out.println(word + ": " + frequency.get(word));
    }

You can also do this using streams as follows.

    list.stream()
        .collect(Collectors.groupingBy(Function.identity(), TreeMap::new, Collectors.counting()))
        .forEach((k, v) -> System.out.println(k + ": " + v));
Marc G. Smith
  • 876
  • 6
  • 8
  • For the input hi.hi it should print hi: 2 but it is printing hihi: 1 – rahul negi Jun 17 '19 at 19:08
  • Your code sample implies that `list` is a list of words. Your comment seems to suggest otherwise. What is contained in the variable list? – Marc G. Smith Jun 17 '19 at 19:13
  • list is a list of words but if an element in a list is hihi it should print the count as 2 not 1 – rahul negi Jun 17 '19 at 19:19
  • To do this, you would need a dictionary to know if a string of letters is a two or more words concatenated together and/or to know if a word is a compound word or two arbitrary words together. – Marc G. Smith Jun 18 '19 at 11:50