TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)2 s/ R, c+ O: y5 {
( `; N% F6 j' \6 q3 i* I* {" @首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。! J8 N. H5 t+ a
; ]4 a# H) H! r例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。) E1 p1 M! E# s
) y' c# `$ O2 s2 @8 U% X2 Y
对数组进行排序
0 E. T- \- R7 G% N
3 g8 a3 D( J7 \4 B8 @& D比如有一个整型数组:
1 J9 H* [1 f3 C' z! T9 [9 A
4 Z' N4 f b0 X3 kint[] intArray = new int[] {4, 1, 3, -23}; ! A9 d( K0 ^- n- y
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:% X$ b* {+ K( u+ ~
7 D5 O7 |% a( S0 P. g e
import java.util.*;
6 p/ Q" g2 o; `. R8 H) [5 J$ `/ Z ypublic class Sort{ ( K% ]) z3 c% k1 c$ a6 [, b2 a
public static void main(String[] args){ % a, d; q2 w- H6 d/ J
int[] intArray = new int[] {4, 1, 3, -23}; $ O C+ Y( s$ {7 k1 C% t/ \
Arrays.sort(intArray);
+ b. J% E/ J) w }
W8 \: V" ~- j* ~* p, K}
% z2 \3 ?2 u. E9 x" ~/ U: T' ?6 q& E这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.
& r- f4 m9 G1 T4 e9 w8 I$ @0 i" g, n8 i6 D5 f2 r' s9 j
如果是字符数组:4 F; T# ~. ]2 q0 M& f7 B
* }* O( X& ~( C/ r) o* h
String[] strArray = new String[] {"z", "a", "C"}; ! D7 \! C4 I; c
我们用:5 \/ R$ R K$ S. c, P" _' o
& ]9 H: `0 Y% K. _
Arrays.sort(strArray); ) s5 \. g9 n' E7 S* J* t' }
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:' Y, s8 f! t5 K8 w" A2 S5 A
2 z* m, w+ \& w2 [9 p$ i- R- l
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); 6 c/ g \2 ]# l4 z6 |: E
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
: D4 c/ g i' O8 j# }- l1 A/ Z2 W6 y# {1 y
Arrays.sort(strArray,0,2); 6 ]6 E% N j0 z: s
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
' O! v8 |3 m8 ]' H% W3 J, a
7 V/ V8 p; x: ], H* t- [3 N当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
; f6 ]/ \" t. l: w4 m
+ @4 C- _- T0 } K2 Gsort(T[] a, Comparator<? super T> c) 3 X" S4 v; p$ W& W4 _* @
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:. q, ]# z/ i+ M+ q) I7 ^
! V6 }- _! M5 u
Arrays.sort(intArray,Comparator.reverseOrder()); 1 F4 y. Y, D: C1 G! L5 I3 F
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:
: f2 A5 y! v) L) C7 E; D0 |, w0 ^
Collections.reverse(Arrays.asList(intArray));
; r5 V6 x: X9 O3 E- |, K4 y0 \+ S得到该数组的反序。结果同样为4,3,1,-23}。( X! U( q5 q* t( h5 \
2 F$ | L: Z( B8 n5 `& D
现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
4 B2 j9 p2 @ w5 S. Q5 ]# q: X# Y8 b# `5 o' u- S
class Name implements Comparable<Name>{
. ?# ~: N5 J! v; B1 p public String firstName,lastName; $ e1 E$ U3 ] }: e4 M7 D+ p
public Name(String firstName,String lastName){ / v4 U' f& P$ F2 `5 }8 T
this.firstName=firstName;
0 U( q( U' ^! ]9 n7 d this.lastName=lastName; : _' x1 A8 d+ J# {$ r5 P3 H
}
7 O w1 b5 Q. T* v! v1 a: I public int compareTo(Name o) { //实现接口
2 I* v6 s! E8 P int lastCmp=lastName.compareTo(o.lastName);
: f1 `' f" x5 e1 G3 H return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); & Q8 O" X( a, L" m! l1 ?
} 8 V0 Q- y3 j1 ?! X
public String toString(){ //便于输出测试 & a: _! {' y6 D0 V5 I
return firstName+" "+lastName;
' l" X; U9 q2 J }
$ y4 i6 @$ N; X! b1 d5 b3 N}
. m& e9 Y/ x; f G+ x) }这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:% B9 r- g: W$ U. ^ L o
) F0 o& ]5 S% x' G import java.util.*; - R; X! G. A) ?1 ~$ C2 D
public class NameSort { 5 J4 X0 d$ {( f" m2 O3 J% f1 S
public static void main(String[] args) {
( c; ?4 k; U5 n% k2 \) _8 ? Name nameArray[] = { 1 ~4 |& r" t! ?( Z
new Name("John", "Lennon"), 5 Y9 Y( R* [/ t$ I
new Name("Karl", "Marx"),
}% \2 l$ w8 p. Z* G new Name("Groucho", "Marx"), $ R! b2 @7 ?! i: d
new Name("Oscar", "Grouch") & _, l- w+ `$ W7 P/ s
}; |
|