3

I'm creating an ArrayList of Map Entry key-value pairs. This is so I can store lots of individual words (as a key) and save the total number of times they are used (as the value).

I need to be able to sort the ArrayList by value so I can order the words by their values.

I have 2 problems:

  1. I don't know the syntax to add a map entry to the ArrayList
  2. I'm not sure how to sort the ArrayList

Any help much appreciated!

protected void addKeywords(Status status) {
    // get tweet
    String str = status.getText();
    // split into an array remove punctuation and make lower case
    String[] splited = str.replaceAll("[^a-zA-Z ]", "").toLowerCase()
            .split("\\s+");
    // vars used in loop
    String thisStr;
    int wordTot;
    Entry<String, Integer> newEntry = null;

    for (int i = 0; i < splited.length; i++) {
        // get word from array
        thisStr = splited[i].toLowerCase();
        thisStr = "hi";

        // if this is the first word to be added
        if (mapList.size() == 0) {
            //this is the syntax that I don't know!
            newEntry.key = theStr;
            newEntry.value = 1;
            mapList.add(newEntry);
        } else {
            boolean alreadyExists = false;
            //iterate through mapList
            for (Entry<String, Integer> entry : mapList) {
                // already exists
                if (entry.getKey() == thisStr) {
                    wordTot = entry.getValue();
                    //increment the value
                    wordTot++;
                    entry.setValue(wordTot);
                    break; 
                } 

            }
            //if we have reached here the value must not be in the arraylist so add it

            //again - this is the syntax that I don't know!
            newEntry.key = theStr;
            newEntry.value = 1;
            mapList.add(newEntry);
        }

    }

}

-EDIT - working code Hi, I've added the new code to add map entries to the ArrayList and that is working great.

I have also updated my sort code and this is working great too:

private void sortMap() {            
    Collections.sort(mapList, new Comparator<Map.Entry<String, Integer>>() {
          @Override
          public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
            if (o1.getValue()>o2.getValue()){
                return 1;
            }else if (o1.getValue()<o2.getValue()){
                return -1;
            }else{
                return 0;
            }
          }
        });
}
Alistair Colling
  • 1,363
  • 2
  • 19
  • 29
  • How about writing your own class to store these key-values? Or [this](http://stackoverflow.com/a/3110644/645270) (implement the Map.Entry interface). It can be sorted using a custom comparator (see `Collections.sort`). – keyser Dec 08 '13 at 20:33
  • 3
    Instead of simulating a Map with your ArrayList of Map.Entries, why not use a Map directly? – user949300 Dec 08 '13 at 20:50
  • @user949300 That's what I asked myself, too. – Marcel Stör Dec 08 '13 at 21:05
  • @user949300 hiya, its so I can order the list based on the values – Alistair Colling Dec 09 '13 at 10:17
  • You can still do that. After everything is done in the Map, call `ArrayList> foo = new ArrayList(myMap.entrySet());` and then sort that array as per Marcel's post – user949300 Dec 09 '13 at 16:52

1 Answers1

8
List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>();
list.add(new AbstractMap.SimpleEntry<String, String>("foo", "bar"));

Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
  @Override
  public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
    return 0;
  }
});

Consider the contract of the compare method:

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

Marcel Stör
  • 22,695
  • 19
  • 92
  • 198
  • Hi, I can't seem to get the comparison working. Can you check my updated question- I've added the new stuff on the end. Thanks – Alistair Colling Dec 09 '13 at 18:42
  • `compare` should `return o1.getKey().compareTo(o2.getKey());`, not `return 0;`. – Radiodef Dec 09 '13 at 18:53
  • @Radiodef, yes it obviously shouldn't always return 0. I don't know what OP's real requirement _is_. Therefore, I pointed him to `compare`'s contract. – Marcel Stör Dec 09 '13 at 19:07
  • Hi @Radiodef and Marcel I want to order the list based on value. The map entries with the smallest values first, increasing in size. Does that make sense? Thanks. – Alistair Colling Dec 09 '13 at 19:09
  • In that case you probably want `return o1.getValue().compareTo(o2.getValue());`. @MarcelStör I guess it's not obvious to the OP. : P – Radiodef Dec 09 '13 at 19:12
  • Hi @Radiodef and Marcel. Thanks for your help, i've edited my question with the code I finally used and the list is sorting great now. Cheers! – Alistair Colling Dec 09 '13 at 19:19
  • @MarcelStör thanks, all sorted now, I've appended my new code onto the end of my question, thanks. – Alistair Colling Dec 09 '13 at 20:12