|
该用户从未签到
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
0 O& \3 P' F, c) N; T: x' _: z) o+ J3 H" I
首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
3 F% h# x$ `& V( V0 ], i$ w. d: N
0 A0 V: c0 Z+ Q, p5 r! Y例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。7 N2 `/ ?6 a, Q6 A/ Y X- t9 X
$ V5 O. W, N9 A% h) Y, h# e对数组进行排序8 }& U6 G" f2 A2 F
2 B J! {4 J4 Y0 T! B7 i
比如有一个整型数组:* C+ p! ^& E- Y3 {6 V
1 A1 E7 r; Z: N0 M+ F8 a5 o @int[] intArray = new int[] {4, 1, 3, -23};
/ t9 K9 V' R$ D' u我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
' x- z. g; Q' ]0 B* K
* D. j2 R% _# u, l# f: ~import java.util.*; % Y" d7 `1 r0 b/ h
public class Sort{
+ A) v6 K7 a6 s( ~; e0 j$ _ public static void main(String[] args){
0 b# }& W! a6 `9 m) ~5 g- Q int[] intArray = new int[] {4, 1, 3, -23}; 5 v2 _; p, G! {; w* H
Arrays.sort(intArray);
6 Z D" O6 i' J6 ~ [9 O }
0 e3 y" n6 u$ @# S" w. A}
7 D: w) N: K. F- H- Q S这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.
' M9 Q `* e( X$ ~) L% P2 [6 m' k
; `( \8 E& Y1 O: |, v. K) x0 {1 O2 q# O如果是字符数组:: H( c' M y9 l3 u$ L }
' I6 T( |) m6 P! D A5 N( w/ ?, bString[] strArray = new String[] {"z", "a", "C"};
# [/ L4 g% Z3 l) [: Q我们用:3 I5 U9 h# f* I- _! \) R: {! Q
6 v3 C/ c* V: H4 zArrays.sort(strArray); + R: o: U% V* w- v2 z
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:
* H, {4 Q& l, r7 y; N/ |) g2 ?0 c# V/ ^8 W
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
|9 r/ P0 w) ?( B. ~当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:- |% ~" H- i3 k) H/ B
" a/ T3 Y! I I0 ]Arrays.sort(strArray,0,2); / N8 i+ d9 M$ H* |
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。( K: |5 M8 R7 k) t( B) E* `
2 O- A$ d, F7 h: Y. ]当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
3 _# z, o. o; c8 B. {! ]% M' {' q8 _! b7 P
sort(T[] a, Comparator<? super T> c)
( \4 l/ m U# M, L7 S/ A3 g. E我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
' z/ v$ L. R. I7 B- _4 c1 {6 F& s! c6 D( O c5 \
Arrays.sort(intArray,Comparator.reverseOrder());
. Z$ n8 z5 | T这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:3 e4 Y% h. p, Y* W2 `* W8 N
0 u7 k4 n1 t3 B( e( `0 k& F
Collections.reverse(Arrays.asList(intArray)); 6 g, m i" v# B* t1 k. @) {. f6 ^: z
得到该数组的反序。结果同样为4,3,1,-23}。
" T! T" _/ j9 Y! Q
y& Q' f L2 C" K1 B: g1 m现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
7 p u, w r2 c- Y' O
- j% z0 {0 z% Y! X7 Z4 t% \" yclass Name implements Comparable<Name>{ 5 r- t% Q7 C3 ^( a
public String firstName,lastName;
6 j0 B6 a0 a. x/ ~; k9 \ public Name(String firstName,String lastName){
/ X# y. N! X& N( k this.firstName=firstName; , [6 [0 b# M X/ T! {
this.lastName=lastName; ! O) [( j- Q& Q: O/ {4 v# @
}
: n! ~" J4 Q) |' J0 G1 X public int compareTo(Name o) { //实现接口
- k* F" _" \7 t t8 p int lastCmp=lastName.compareTo(o.lastName);
) n- C8 \3 t. k" v- |: s: m return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); 0 U3 G d, g, Q- q1 w, R- i# `& }' t p
} . h B9 J5 q6 t1 u' `' P
public String toString(){ //便于输出测试 # l$ a& M. \2 a3 Q
return firstName+" "+lastName;
0 N2 h0 @: o/ h: \% q, }1 t } 0 X5 ]& H8 w: X( S% P
} , m0 u2 W/ N. x8 }$ q$ u" A
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:8 U" l* K3 V# H l4 h
+ w3 U' X! V8 S% X E* U7 z
import java.util.*;
. x& Z3 K$ |7 J/ h2 V public class NameSort {
& @% J: k8 J' S, U. S public static void main(String[] args) {
# A" ?9 X* J8 s0 m7 G0 F1 R Name nameArray[] = {
5 Z$ ?4 g1 h6 S% X7 f new Name("John", "Lennon"), * D0 b. S+ Y$ `9 W, t6 C
new Name("Karl", "Marx"),
, {! `+ W6 w2 R1 W" L# H% ?$ X$ z new Name("Groucho", "Marx"), 9 z2 l* j! n8 l' [; j) @2 G. |
new Name("Oscar", "Grouch")
' `+ _4 | N* `( Z }; |
|