Java: Sort a list of words by length, then by alph

2019-02-19 07:51发布

问题:

I am told to have a list of words sorted by length, and those that have the same length are sorted by alphabetical order. This is what I have for the method that does that so far.

public static void doIt(BufferedReader r, PrintWriter w) throws IOException {
    TreeMap<String, Integer> s = new TreeMap<String, Integer>();
    ArrayList<Integer> count = new ArrayList<Integer>();
    String line;        
    int length;
    while ((line = r.readLine()) != null) {
        length = line.length();

        s.put(line, length);
        if (!count.contains(length)){
            count.add(length);
        }
    }    
    Collections.sort(count);
    System.out.println(count);
}

My mindset was to use a TreeMap to keep the String, and the length of the word as the key. I also have an ArrayList that keeps track of all the word's lengths without any duplicates, it's then sorted.

I was hoping to somehow call on the TreeMap for the key value of 5, which would list all the words with 5 letters in it.

I was wondering if I'm on the right track? I've been playing around for over an hour and can't seem to figure out what I should do after this. Am I approaching this from the right angle?

回答1:

The easiest way would be to write a Comparator<String>. The Comparator<String> would receive two words, and compare them. If the first was shorter than the second, it should return -1. If the second was shorter than the first, it would return 1. If they are the same length, it should call the default String compareTo method. You can then simply sort your list using this custom Comparator.



回答2:

you want to use a string comparator that compares by length 1st. like so:

public class LengthFirstComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {             
        if (o1.length()!=o2.length()) {
            return o1.length()-o2.length(); //overflow impossible since lengths are non-negative
        }
        return o1.compareTo(o2);
    }
}

then you could simply sort your Strings by calling Collections.sort(yourStringList, new LengthFirstComparator());



回答3:

You can do that using simple List. Try following code.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


/**
 *
 * @author Masudul Haque
 */
public class LengthSort {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        list.add("cowa");
        list.add("cow");
        list.add("aow");
        Collections.sort(list, new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                if(o1.length()>o2.length()){
                    return 1;
                }else{
                    return o1.compareTo(o2);
                }
            }
        });

        System.out.println(list);
    }
}


回答4:

By far the easiest and best way is to write a custom comparator as other answers say.

But to do it a similar way you were attempting would be to make the length the key and rather then having a single string as the value have a list of all the words of that length. So a map of the form

Map<Integer,List<String>>

You could then call the key of any length and return a sorted list of words like this

Collections.sort(yourMap.get(theLength))

BUT far more complicated then just using a comparator



回答5:

You can use Java 8's lamba utilities to make concise functions that prevent the clutter of using comparator classes, like so:

Collections.sort(words, (string1, string2) -> Integer.compare(string1.length(), string2.length());

-Example taken from Effective Java by Joshua Bloch



标签: java sorting map