-1

I'm trying to count letters in a string in descending order. But my code only picks up some of my letters. Why is this?

Code:

import java.util.Iterator;
import java.util.TreeMap;
import java.util.TreeSet;


public class CharacterCount {
public static void main(String[] args)
{ 
    TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();

    String s = "holy brown cow now"; 

    for (int i = 0; i < s.length(); i++) { 
        char ch = s.charAt(i); 
        int count = 1;
        if(tm.containsKey(ch)){
            count=tm.get(ch) + 1;
        }
        tm.put(ch, count);
    }

    TreeSet<CharItem> ts = new TreeSet<CharItem>(); 
    Iterator<Character> it = tm.descendingKeySet().iterator();

    while (it.hasNext()){
        char ch = (char) it.next();
        int count = tm.get(ch);
        CharItem ci= new CharItem(ch, count);
        ts.add(ci);
        }
        Iterator<CharItem> it2 = ts.iterator(); 
        while(it2.hasNext()){
            CharItem ci=it2.next();
            System.out.println(ci.getCh() + " occured " + ci.getCount() + " times"); 
        }
    }
}
class CharItem implements Comparable<CharItem>{
    private int count;
    private char ch;
    public CharItem(char c, int i){
        count = i;
        ch = c;
    }
    public char getCh() {
        return this.ch;
                }
    public int getCount() {
        return this.count;
        }

    @Override
    public int compareTo(CharItem b) {
        return b.count - this.count ;
    }
}

added the charitem above

CJBS
  • 15,147
  • 6
  • 86
  • 135
Susan
  • 1
  • 2

1 Answers1

0

The problem is with class CharItem as it should be modified.

public class CharItem implements Comparable<CharItem>{
        private int count;
        private char ch;
        public CharItem(char c, int i){
            count = i;
            ch = c;
        }
        public char getCh() {
            return this.ch;
        }
        public int getCount() {
            return this.count;
        }

        @Override
        public int compareTo(CharItem o) {
            int result = Integer.compare(count, o.count);
            return result == 0 ? Character.compare(ch, o.ch) : result;
        }

    @Override
    public boolean equals(Object o) {
        return o instanceof CharItem && ((CharItem)o).ch == ch;
    }
}

The method compareTo must be in consistent with equals method as if two objects are equal via equals() , there compareTo() must return zero otherwise if those objects are stored in TreeMap/TreeSet they will not behave properly. You need to use Iterator<CharItem> it2 = ts.descendingIterator(); in the code:

public static void main(String[] args) {
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();

        String s = "holy brown cow now";

        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            int count = 1;
            if (tm.containsKey(ch)) {
                count = tm.get(ch) + 1;
            }
            tm.put(ch, count);
        }

        TreeSet<CharItem> ts = new TreeSet<CharItem>();
        Iterator<Character> it = tm.descendingKeySet().iterator();

        while (it.hasNext()) {
            char ch = (char) it.next();
            int count = tm.get(ch);
            CharItem ci = new CharItem(ch, count);
            ts.add(ci);
        }
        Iterator<CharItem> it2 = ts.descendingIterator();
        while (it2.hasNext()) {
            CharItem ci = it2.next();
            System.out.println(ci.getCh() + " occured " + ci.getCount() + " times");
        }
    }

And then you will get:

o occured 4 times w occured 3 times occured 3 times n occured 2 times y occured 1 times r occured 1 times l occured 1 times h occured 1 times c occured 1 times b occured 1 times

which I believe is what you want. Another option is to try:

TreeSet<CharItem> ts = new TreeSet<CharItem>(Collections.reverseOrder());

This will insert the elements itself in reverse order and the sign returned by comparator will actually be reversed.

akhil_mittal
  • 23,309
  • 7
  • 96
  • 95
  • I'm looking to do this in descending order (o occured 4 times w occured 3 times...... ect)... @akhil_mittal – Susan Jun 30 '15 at 04:04