tags:

views:

175

answers:

10

I have a String list

ArrayList<String> list = new ArrayList<String>();

with each item:

list.add(week+" "+year);

where week and year are integers.

How to sort this list to ascending order?

A: 
Arrays.sort(list);

or Arrays.sort(list, Collections.reverseOrder());

AntonioP
OP apparently wants to sort the list chronologically... However, '52 2009' comes alphabetically after '01 2010'.
eumiro
Then he should have specified so, his question is "how to sort this list". The answer is given.
AntonioP
Hi, sorry that I did not specify preciously, I actually need this list to be sorted chronologically.
Mellon
A: 

If you simply want to sort by the string value (which will be alphabetical order):

Collections.sort(list);

If you wanted to sort chronologically, you could implement a custom Comparator and pass it to the sort method:

public class MyComparator implements Comparator<String> {
    public int compare(String first, String second) {
        // Split the string and compare the ints here
    }

    public bool equals(Object o) {
        return this == o;
    }
}

And then:

Collections.sort(list, new MyComparator());
Justin Niessner
That will be based alphabetically only. I doubt if that's what the OP wants.
Ashish
chronologically needed, thanks.
Mellon
+3  A: 
Collections.sort(list, new Comparator<String>() {
  public int compare(String a, String b) {
    // Your string ordering logic here. (I won't write that for you.)
  }
});
missingfaktor
@Downvoter, care to explain your downvote?
missingfaktor
@missingfaktor - They got me too...not sure why.
Justin Niessner
+5  A: 

You need to write a comparator which splits week and year, compares the year before week (if the year fields are equal). BTW You should put week and year in an object to avoid the splitting.

stacker
+1 Good point about the object!
Ravi Gummadi
A: 

If you want to sort by chronological order, you're going to have to either swap the year and week so that it's year+" "+week then do a simple alphanumeric sort, or write your own Comparator that accepts two items from the list and reports which one comes first.

Also, consider creating a class that has week and year attributes. Use objects of this class to store your week/year values and then you can output it in any way you want, in addition to having it be easier to sort.

Jeff
+2  A: 

Implement a Comparator to compare the pieced out week and year values. Use that comparator to sort the list. That should work. Sample implementation is provided below

class WeekYearComparator implements Comparator throws NumberFormatException{
 public int compare(Object weekYr1, Object weekYr2){

 String[] tokens1 = ((String)weekYr1).split(" ");
 int week1 = Integer.parseInt(tokens1[0].trim());
 int year1 = Integer.parseInt(tokens1[1].trim());

 String[] tokens2 = ((String)weekYr2).split(" ");
 int week2 = Integer.parseInt(tokens2[0].trim());
 int year2 = Integer.parseInt(tokens2[1].trim());

 if( year1 > year2)
  return 1;
 else if( year1 < year2)
  return -1;
 else if(year1 = year2){
   if(week1 > week2)
    return 1;
   if(week1 < week2)
    return -1;
   if(week1 == week2)
    return 0;
 }

}

Arrays.sort(list, new WeekYearComparator);
Ravi Gummadi
Subtle. But I think tokens2[0].trim() to tokens2[1].trim() ...
AntonioP
@AntonioP: Thanks for pointing out. Corrected it
Ravi Gummadi
A: 

Create a list of Calendar objects using the YEAR and WEEK_OF_YEAR. Sort that, and then convert the result to a list of strings.

Peter DeWeese
A: 
List<String> weeks = new ArrayList<String>();
weeks.add(1 + " " + 1958);
weeks.add(32 + " " + 2007);
weeks.add(32 + " " + 1999);

Collections.sort(weeks, new Comparator<String>()
{
  public int compare(String o1, String o2)
  {
    int y1 = Integer.parseInt(o1.substring(o1.indexOf(" ") + 1));
    int y2 = Integer.parseInt(o2.substring(o2.indexOf(" ") + 1));
    if (y1 == y2)
    {
      int w1 = Integer.parseInt(o1.substring(0, o1.indexOf(" ")));
      int w2 = Integer.parseInt(o2.substring(0, o2.indexOf(" ")));
      return w1 - w2;
    }
    return y1 - y2;
  }
});

System.out.println("weeks = " + weeks);
Boris Pavlović
+10  A: 

I'll recommend to create a data structure that contains the data you want and implements comparable.

class WeekOfYear implements Comparable<WeekOfYear> {
    private int week ;
    private int year ;
    public WeekOfYear(int week, int year) {
        this.week = week ;
        this.year = year ;
    }
    /**
     * ...
     */
    public int compareTo(WeekOfYear other) {
        int delta = this.year - other.year ;

        return (int)Math.signum(
                delta != 0 ? delta : (this.week - other.week));
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder() ;
        builder.append(week > 9 ? "" : "0") ;
        builder.append(week).append(" ") ;
        builder.append(year) ;

        return builder.toString();
    }
}

List<WeekOfYear> weeks ;
weeks = new ArrayList<WeekOfYear>();
Collections.sort(weeks) ;
XecP277
The proper way would seem to be writing your own object, then overriding comparison. This isn't always the easiest or quickest, but if you have the time, it's the right way.
Robolulz
What is with the extra space before the semicolon?
Steve Kuo
Just an old habit of the times where i started coding, to learn the APIs by name and not rely on syntax highlighting or auto-completion of function names, class name, variable, etc, I've use to code in notepad. Adding the extra space allow me to copy the word without the semicolon both using the mouse and moving left or right with control.
XecP277
+1 (and nice answer)
stacker
A: 

General solution:

public static <T> void sort(List<T> list, final List<Comparator<T>> comparatorList) {  
       if (comparatorList.isEmpty()) {//Always equals, if no Comparator.  
            throw new IllegalArgumentException("comparatorList is empty.");  
       }  
       Comparator<T> comparator = new Comparator<T>() {  
       public int compare(T o1, T o2) {  
               for (Comparator<T> c:comparatorList) {  
                   if (c.compare(o1, o2) > 0) {  
                     return 1;  
                   } else if (c.compare(o1, o2) < 0) {  
                     return -1;  
                   }  
               }  
               return 0;  
         }  
       };  
       Collections.sort(list, comparator);  
  }  
卢声远 Shengyuan Lu