|
该用户从未签到
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
% j* P5 m. _: I" p; z8 m, E) ~+ o% i. x& L- d- t( v' J1 R
首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。2 L7 \5 Z9 w6 F4 f* b! F
; w1 E* U$ H, ^ f$ h% Z例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。8 g, B& Y8 T. G) y, Z
2 i: j6 ]/ {( d8 A* y* Z
对数组进行排序
% |8 q) ]; P3 b! }" @, t- M1 }0 R; E S1 z; @/ a$ c. l
比如有一个整型数组:% V0 s; q& ~* E+ c k6 l
7 ?. i* ]7 \" K) [" v" T! j
int[] intArray = new int[] {4, 1, 3, -23}; # u; G' o3 W5 ^6 q
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:# \" r9 T/ H c) n
" V$ |! P8 _1 j! y. }$ D& Himport java.util.*;
: \5 h" ?3 v5 _& u. @# Xpublic class Sort{ ! B3 A8 R; W' Q; V" N
public static void main(String[] args){ $ i7 Y1 {* t* ^ [$ \* J8 S4 H6 z: v
int[] intArray = new int[] {4, 1, 3, -23};
% X1 E; L! [, b. n7 `1 D$ ~ Arrays.sort(intArray);
- B; b3 V9 K: B } # y+ H4 ?+ m. b$ B! u1 S+ ^
} . W' ]7 d2 Q' s; Z" ~
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.
/ }) {6 L$ l6 B" o b2 i2 [, k5 W& M5 P0 \
如果是字符数组:! D) h) Z5 W1 H
; v/ Q0 F) P7 j. C- F
String[] strArray = new String[] {"z", "a", "C"}; ' o/ j! z' j5 S. l
我们用:
$ b6 E: c& ^* }) I- g9 T
8 R& }$ }0 u) H0 LArrays.sort(strArray); - [4 U6 q4 \7 o3 R- c, [
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:
1 w4 h, M9 ?) ]) J, b, _# R' b0 c) _/ M$ q( F/ A
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
( { s2 d6 p \+ T7 W当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:0 J, T- B; @0 R
1 P- l& E' D+ i* V: aArrays.sort(strArray,0,2);
" m$ {9 T- d2 q- U* U这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
8 q, a4 J& c" a7 k5 Z
2 h" G3 D8 a4 D) Q' R当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
; q9 t t s* ]( F6 J
' ~# \# o# e: X2 \2 P: Lsort(T[] a, Comparator<? super T> c) - O* h' U! @+ @4 x
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
2 ~" R+ [) l0 s Y0 @) z* w8 |& u& Z$ H u6 R, D9 p/ v7 T( m
Arrays.sort(intArray,Comparator.reverseOrder()); " ~% Y* C$ v, E6 ]
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:
% m | X: Y, k2 t, U# A/ M, q8 |& \# b- ^2 q+ O
Collections.reverse(Arrays.asList(intArray));
. E, H) t) O# z: `, \得到该数组的反序。结果同样为4,3,1,-23}。
* t% c! M8 |/ V' d2 T) a
L8 E; b2 S; t0 K4 ~现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:3 K/ z" P" ~* X9 P' P1 [; z
6 |& O; e! ?/ ]9 \class Name implements Comparable<Name>{ ( J2 t& M4 H v$ n
public String firstName,lastName; ) o1 q- X" @9 ~$ t
public Name(String firstName,String lastName){
# W0 M" V$ E' z% a- J this.firstName=firstName;
2 m" Y# y9 N1 \ this.lastName=lastName;
3 G* G! b" x2 t5 z }
E( T( {0 c7 r. M public int compareTo(Name o) { //实现接口 0 O9 z, E7 t0 v* Y% G- B9 r! _
int lastCmp=lastName.compareTo(o.lastName); 0 _" O( `4 \- H, K
return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
8 ]* S6 E" f" C* u( ^ } . B2 N. X. W2 m
public String toString(){ //便于输出测试 + a; Z8 R" Z8 ]4 [
return firstName+" "+lastName;
: t: u8 }5 S' m/ u1 `) o } / |" i) X0 @" `
} % f e' w' V5 Q* N
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:" a5 F8 {' x; w. r
: y% k/ i% N8 H3 g% o4 Y! z
import java.util.*; : j( x5 k3 E" B" @! B
public class NameSort {
1 I# ` s! g9 R+ D/ F public static void main(String[] args) { 8 u" w6 h4 p7 A3 y
Name nameArray[] = { 8 Q4 {# D( l) L' B
new Name("John", "Lennon"),
0 F# U2 L. x# x% B8 u2 R/ L# i new Name("Karl", "Marx"), ! M% t# g! p5 K8 b* M* k
new Name("Groucho", "Marx"),
# d- V6 {+ ^( ~) x4 ~6 Y3 f5 Z new Name("Oscar", "Grouch")
% d7 r" Q; n; y) @$ X' ^ }; |
|