该用户从未签到
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)$ q2 K) V( Z0 P. _' R' ~
! K% C' W) v9 a4 N- n5 `6 j5 E
首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
9 F U! k1 Y# x( z, Y! i9 n& D7 B9 c1 R
例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。/ H( O0 D5 q6 P' u$ W; `7 M" e# D6 q
) {3 _% |2 V# C/ {( e% c
对数组进行排序, Q/ k) D" D) v3 j6 s
I4 d% }7 G1 T8 m* i! e# D4 b3 I
比如有一个整型数组:
/ y7 g! f0 v/ y5 _. a
8 P5 ^/ y7 r% O- b; Uint[] intArray = new int[] {4, 1, 3, -23};
5 ?/ ~+ H1 V. U! H9 z我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:+ G9 F: y2 T/ n9 {9 J# _2 y
7 v4 }9 w5 `5 c& i0 x
import java.util.*;
7 w. [+ a, r, C/ l6 L+ opublic class Sort{ 4 q5 d7 M0 U% a; P- h7 b) u9 o* W
public static void main(String[] args){ # v8 j. a1 J* p
int[] intArray = new int[] {4, 1, 3, -23};
7 D; I0 | l8 L/ B6 G Arrays.sort(intArray);
$ y" S2 v* L# K. o }
& o2 O& x# @; h9 u% u4 c} 7 i. @. \0 F5 j3 E
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.1 d5 Z4 W9 I2 x" e
$ a K/ e% M5 p8 T8 F4 W如果是字符数组:
4 {0 y/ K h( S0 m; e: x7 `8 t) E
% V% G5 {8 Y# m% M( x/ F: dString[] strArray = new String[] {"z", "a", "C"};
* B, i* a3 G s0 _我们用:1 E$ d. q9 d+ M
- p. X+ M8 J5 S6 d4 _. m! N s6 DArrays.sort(strArray); + Q0 A1 A1 p5 b% h1 @! U( e! w
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:! C D: ~" f6 b& ^# v4 p0 G
2 u9 n f4 P$ y4 s. ?6 d( |# }Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); { t2 @4 c8 p3 c) U$ N" C; Y
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:6 h7 ^- _* s+ c0 a
: G4 ^5 }- R/ q3 k& FArrays.sort(strArray,0,2);
4 G/ P3 ?+ z8 N( S. m+ |这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。! P1 } @4 d- q
( I l2 j6 K% T当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
3 y% j' N& A& X: \3 l: g
' R* f0 g9 s T ^, O1 @% O2 vsort(T[] a, Comparator<? super T> c) - E% L1 ~7 {" T5 H
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
( t; T- @# \, [( ^! a) F/ U, C* q* W5 Y* v4 k ?. d! r( i$ u
Arrays.sort(intArray,Comparator.reverseOrder()); " b% J; ^% E% f+ n* d% f
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:
2 e! O, z8 }0 Y+ o2 g$ w: ~7 V' U3 x
+ r4 r: }$ R3 E6 h# Y" S. eCollections.reverse(Arrays.asList(intArray)); - Z% v% t7 s' ~3 K# f+ u ]# ~
得到该数组的反序。结果同样为4,3,1,-23}。
6 D0 K3 ]9 Z& J0 Y5 h& [5 z
- \ O: x+ o1 ^9 ^8 w& R# `. L* c现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:# o- ^4 [9 V4 g9 {- m) ~! J8 m
( K* F- C1 c+ f4 F$ }" T3 ?
class Name implements Comparable<Name>{ $ \+ A& _9 L8 \: Z1 l4 d! _
public String firstName,lastName; , w% c9 _ v; Y l* Y( J
public Name(String firstName,String lastName){ # W$ _; l+ @0 R7 I P0 _& C: u1 M
this.firstName=firstName;
3 k) i V+ F$ e: P this.lastName=lastName;
' V8 F1 o4 Y/ y) t& g$ \# J } 5 m8 m. \" {% q# `- W, S2 J* y5 E
public int compareTo(Name o) { //实现接口 / Q7 b9 Z% v# w- T
int lastCmp=lastName.compareTo(o.lastName);
# e9 U9 S0 i, F- H1 I* f: L return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); 1 ~. f- Y* w' k( x
} 4 Z. D8 B; c M
public String toString(){ //便于输出测试
2 ~( f( U7 i! q1 a4 Q% K6 U return firstName+" "+lastName; 2 v" R4 w0 A# I9 s- ], Z
} . T/ r6 m; D) t! i' R9 o7 i
} ' ^! l# e8 M; L% R/ ]
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
0 D' F7 {3 C' v/ }7 C7 `" k, Y! A" Z. [, U# y' `
import java.util.*; 4 p( X0 f# Q6 c5 Z; n
public class NameSort {
* h! c4 r1 i1 p+ W) k3 G public static void main(String[] args) {
; d: s- T. k+ m+ ^- r0 l Name nameArray[] = {
J8 M1 ` m ?7 o8 U) S; h- S new Name("John", "Lennon"), : N7 Y: W1 N9 H! w! Y/ g/ }$ W- W
new Name("Karl", "Marx"),
2 N, [" N* |0 ^ @3 J! l6 t7 p new Name("Groucho", "Marx"),
7 Z; J5 h4 i2 b1 Q+ a) s new Name("Oscar", "Grouch")
& j0 p, n! m' T* I/ m3 i7 D }; |
|