I have a list of order objects. Each order object has 5 instance variables. Is there a way I can sort this list based on any of these instace variables? I need to implement the comparable开发者_如何学运维 interface. But in that case, how could I sort on a specific variable?
You can define static
Comparator
s in the class like this,
public static final Comparator<Order> NAME_COMPARATOR = Comparator<Order>(){
public int compare(Order o1, Order o2) {
// provide an impl here using order name
}
}
public static final Comparator<Order> ID_COMPARATOR = Comparator<Order>(){
public int compare(Order o1, Order o2) {
// provide an impl here using order id
}
}
And then pass those while sorting like this,
Collections.sort(list, Order.NAME_COMPARATOR);
Collections.sort(list, Order.ID_COMPARATOR);
Your question has a lot of ambiguity. Here's an example of a 5-field class. This class is sortable using Comparable
, which in this case sorts by field a
, then field b
, and if a
and b
are identical, the two are equivalent in sort order. If you implement Comparable
, you probably also need to implement equals()
and ensure that it is consistent, as demanded in the Comparable
interface spec. See also javapractices.com "implementing compareTo()
" for some good detail.
Working example:
import java.util.Arrays;
class SortableThing implements Comparable<SortableThing>
{
final String foo;
final int a, b, c, d, e;
public SortableThing(String foo, int a, int b, int c, int d, int e)
{
this.foo = foo; this.a = a;
this.b = b; this.c = c;
this.d = d; this.e = e;
}
@Override
public int compareTo(SortableThing o)
{
if (this.a != o.a)
return this.a - o.a;
else if (this.b != o.a)
return this.b - o.b;
else return 0;
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof SortableThing)) return false;
SortableThing st = (SortableThing)o;
return st.a == this.a && st.b == this.b;
}
@Override
public String toString()
{
return new StringBuilder().append(foo).append(": <").append(a)
.append(',').append(b)
.append(',').append(c)
.append(',').append(d)
.append(',').append(e).append('>').toString();
}
public static void main(String[] args)
{
final SortableThing one, two, three, four;
one = new SortableThing("one", 4, 2, 42, 42, 42);
two = new SortableThing("two", 2, 3, 42, 42, 42);
three = new SortableThing("three", 2, 2, 42, 42, 42);
four = new SortableThing("four", 1, 50, 42, 42, 42);
SortableThing[] list = new SortableThing[] {one,two,three,four};
System.out.println("Before: "+Arrays.deepToString(list));
Arrays.sort(list);
System.out.println("After: "+Arrays.deepToString(list));
}
}
Output:
Before: [one: <4,2,42,42,42>, two: <2,3,42,42,42>, three: <2,2,42,42,42>, four: <1,50,42,42,42>]
After: [four: <1,50,42,42,42>, three: <2,2,42,42,42>, two: <2,3,42,42,42>, one: <4,2,42,42,42>]
You can do this pretty elegantly in Scala.
val sortedOrders = orders.sortBy(o => (o.a, o.b, o.c))
Sorts the orders
list by the the field a
first, then by field b
, and then by field c
.
If you mean 'order by a,b,c', I wrote a blog to solve it: 对java.util.List多字段排序. See 2nd snippet of code, sorry it' Chinese, but code and comment are English:)
Assuming you have "get" methods for the instance variables you can use a Bean Comparator so you don't have to write custom code.
精彩评论