|
该用户从未签到
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)- [/ Z( C4 P. w+ b% Q
* Z% N$ I* Y3 Y. ?: M
首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。- k; T8 B4 o7 D
' w$ B; d7 M% t例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。) e' Z! n- O1 q% Z- D+ r1 U
+ ^" P. V: A0 U+ |6 J9 m& p
对数组进行排序
9 l% J% w' ^2 a2 a: x: ~) k
& |3 |/ H4 E5 V& |比如有一个整型数组: t. G1 m2 m8 D2 I& f( {, j
- [/ E6 p# I. ^8 L) F. K" L& m
int[] intArray = new int[] {4, 1, 3, -23}; ( ?6 y: F1 l, T) F; |2 f
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:1 z Q$ d( H( d! L* ?* I
' m+ i1 w) @- N5 U/ f+ _! qimport java.util.*; % }( \: ~) y q
public class Sort{
& G! a) s3 g) X8 m8 j& ~$ x( D public static void main(String[] args){
! ~/ R- A; p0 ^% P int[] intArray = new int[] {4, 1, 3, -23};
) b7 }/ T- X- x3 T/ b Arrays.sort(intArray);
4 c! G+ @+ w/ r# {! {5 }4 I } D/ I/ A U! d+ A" [( V; k% k g2 z
}
* Y* h& n! }# L) E' @这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.
: Y% k; h# X9 r! J2 c7 Z
+ J3 p- D. e6 R4 \. v/ [; ^如果是字符数组:% J0 H* K0 I( G4 f' p
- T, f+ G( ?4 Z! ]& x: x' `) u/ S: XString[] strArray = new String[] {"z", "a", "C"};
) _" M& l. l9 ?/ ~9 ~6 S# j我们用:
" b0 U! w% \. u; K, w6 c" S" o* P$ s z/ q
Arrays.sort(strArray);
0 N9 P$ k6 m% \7 H3 g" H8 v( q5 S进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:; K2 o$ A! a1 Z
( N, m9 D% d9 s& t
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); $ |( \ S6 o5 B, Z: q: ^5 R
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:5 u/ O! ~/ t/ q9 E
1 v3 N3 Z- @# R+ c% SArrays.sort(strArray,0,2); + v4 S) l% T0 X' u. Q) Q
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。! K; c6 g6 `8 q9 u ?9 ?2 F' U o
- ?& ^& M+ [: g N! L, c2 r
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个- h7 W( ]: @; O: u( K& v
1 W& r( U. c; S& g: _- M+ Psort(T[] a, Comparator<? super T> c)
$ Y; k, b: A- r3 \我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
# |( C7 ]. a5 H0 j4 A+ m) l3 }
. a- s0 X! E: K. X# M* G3 H% N6 M TArrays.sort(intArray,Comparator.reverseOrder());
- j+ h0 ^' h; @7 m. I; Q2 z4 ^6 W这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:" F' S t8 m% w, L& o
4 Z) E4 n8 u1 K! X! L+ TCollections.reverse(Arrays.asList(intArray)); 3 m; ~9 l, ~1 r( S
得到该数组的反序。结果同样为4,3,1,-23}。
: p$ W8 [+ Q8 q' X- y
M! F, V! a. a0 d7 u现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
. Y# V# R/ F1 ?5 z/ k% A# R& V& H+ O& F6 Y* l0 N8 o4 v
class Name implements Comparable<Name>{ * G) S' ~9 J$ J% Q! m! s
public String firstName,lastName;
1 k9 G5 |: O0 h public Name(String firstName,String lastName){ # N Y- ?, k/ H/ v* e
this.firstName=firstName;
, u3 S4 c; y6 g% u) B5 } this.lastName=lastName; 4 }: n9 x. T5 v: E
}
- G$ p4 U( r+ Y public int compareTo(Name o) { //实现接口 h4 P" V3 n; w) _+ l2 w1 V
int lastCmp=lastName.compareTo(o.lastName);
* A( N7 N0 N7 \/ X4 r return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
" l0 W4 E+ I0 c5 y/ @ }
& F- b6 K1 q5 c A, T6 b1 x. _ public String toString(){ //便于输出测试
$ r' |% K% v3 }, y* R8 Y$ M: e return firstName+" "+lastName; 9 e& ?) @! b! }; K5 |$ {
} * I# _) p0 _# s
} ) _9 o4 u+ G9 w! o; T
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:. c( a' [9 }, t. K- ]5 _
/ q4 `7 j# Q+ }: @3 B8 a- ^; n
import java.util.*;
, F2 I' B, t2 a$ [ public class NameSort { / J5 a0 E& D( H: p3 Y
public static void main(String[] args) {
9 Q; B. M! Q0 I. o) J" q Name nameArray[] = { : G$ ?5 p! @6 s6 y( B* u! m3 {
new Name("John", "Lennon"), $ V6 ]% l- _9 v! O/ A6 |! Q
new Name("Karl", "Marx"),
+ u m* v8 |0 m3 j a% G new Name("Groucho", "Marx"), 0 l. ^$ E2 s; ^# `. O9 m& n
new Name("Oscar", "Grouch") 8 J! T& b2 e# f: V
}; |
|