该用户从未签到
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
" |/ @7 J6 T6 B8 x% R
: _* Y2 f5 Y- t8 e8 G首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。5 ^* p5 }2 D, \6 r; h
# ~ t! t- _+ K( r3 u! ]8 l- Z例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。& d( ~; b6 Y* Q
, Y4 }% d9 n/ G9 ~* W
对数组进行排序
0 C4 n9 T7 d& {9 \: \$ d8 ~# X' a2 q: o! v
比如有一个整型数组:
, D5 X. z) s# ?+ u9 G$ |! A+ z4 d. g% `/ s8 K2 h/ r
int[] intArray = new int[] {4, 1, 3, -23};
5 y7 |- U4 N5 W, t E3 H2 O, X我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
, j' O7 D! a* u4 d* ?. A, [, M5 h5 _& A6 W. g
import java.util.*; 2 _! X' Y& C/ Y* Q" M1 J
public class Sort{
+ M8 T7 D/ ^0 |, s' j& R P5 y public static void main(String[] args){
# t3 [' w/ t, T. \ int[] intArray = new int[] {4, 1, 3, -23}; 2 L @. |' ` u
Arrays.sort(intArray); & H3 v- k. @9 k# z% O" |9 E
}
% B' M$ w4 s% s' o! q% ]}
! B6 |1 J3 x7 r这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.
) @# L, j1 w4 E; a: Q7 a, R8 A' O) T$ l: m- D/ X5 T
如果是字符数组:
/ ]6 m- L) X3 x2 d0 g5 \" n
9 N6 F/ w4 \! {5 ?9 KString[] strArray = new String[] {"z", "a", "C"}; 8 C2 g. Y+ U* M, H7 {: v. W' h% I) L
我们用:
8 S d4 J9 }8 e- m# I: C" |4 C
+ `8 P; D" ?, r0 eArrays.sort(strArray);
4 x& m U. ^7 v4 V& h9 a) w进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:
# a5 { a* w8 u& I) Y" |& ^) q$ z# z4 j9 [" |; T4 V) q
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
8 \. p' g3 o' ~$ T8 J当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
4 }0 t+ }0 |- s- v/ S! t4 E2 \: I. M4 i1 e y
Arrays.sort(strArray,0,2);
; t! L; X2 u; f0 r3 ]; n2 h这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
$ y( R$ Q/ {9 l# p4 d. K/ N& s) t, _; U0 O" J
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个0 L1 u7 y. j4 b9 x
/ Q8 s+ \' x! M. N* a3 V
sort(T[] a, Comparator<? super T> c) 1 N# r* O& |6 o* v& O* P
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:' T* W2 r3 g/ T+ m! m/ `& w* l
* Z. t$ W8 f: Z9 S/ F. d1 rArrays.sort(intArray,Comparator.reverseOrder()); . ]5 J; L- N$ F& g# I0 |" R: N
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:
! e+ h0 P' ]1 X9 T& r3 i9 E- e6 s3 e! {+ q
Collections.reverse(Arrays.asList(intArray)); ( F1 B) u9 T* M: j: c4 {: R
得到该数组的反序。结果同样为4,3,1,-23}。* T# M ~8 ?+ U9 Q4 l3 W
w4 Z* a+ ]6 ?0 s) U1 Q现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:% N* V3 m. T9 a- o& P. N* w3 [! m
: O0 x5 J* N+ x f1 o
class Name implements Comparable<Name>{
9 B+ N; Y5 D3 s public String firstName,lastName; 0 W& j. a, J$ a3 N
public Name(String firstName,String lastName){ 2 t" c$ ]6 {8 y
this.firstName=firstName; - T! w% v( ^$ l9 |: S8 E, }# u W
this.lastName=lastName; . \" s& p5 w" e) t: f( E
}
7 x. R$ L9 Q# M6 h public int compareTo(Name o) { //实现接口
0 |) }% b' y) ^ C5 l int lastCmp=lastName.compareTo(o.lastName); 8 w, P, h4 \7 H% I9 V1 M$ z
return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
* a( y n0 y% o4 N1 S9 I* X3 ? } 0 `+ K* O" F$ O2 G+ q" N! f! s
public String toString(){ //便于输出测试 % e9 z4 S$ C; k& r% i
return firstName+" "+lastName; 3 `2 T2 z& P! H F3 |
}
/ a' H' S6 U# o" M }} 6 E4 n4 |1 C# m
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:5 P0 b2 H, V& G7 O" d( h
6 J, v( a% L- N0 @6 M import java.util.*;
8 ~" F4 [/ ?/ a6 u* S public class NameSort { % D* W6 w! ^( v+ S! l- {* Q& u8 `2 @
public static void main(String[] args) {
/ W4 U3 f3 ~2 C- {$ ^7 e* m! e1 Z4 Q Name nameArray[] = {
0 b1 j5 H% J! W' Y9 s; [& ^ new Name("John", "Lennon"), 5 Z0 n" A% ^/ J: a5 G
new Name("Karl", "Marx"), " |$ D# S' f4 Z/ S
new Name("Groucho", "Marx"),
; ?/ k0 n, F6 a- n9 t) o! ? new Name("Oscar", "Grouch") $ Q5 \8 I8 v& Y0 z, G) D' `5 L
}; |
|