TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
. ^- k4 K+ v' h, q
& R4 k2 n& E$ R! q; t( R+ n首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。& ~5 f$ r" k B8 z) i! X
; L! H- E# S' s) n2 I. n1 z: x1 e
例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。* F0 d% ^# B6 q* P3 b
2 @1 ?. `' ?% a% V对数组进行排序
5 Y0 ]2 {9 V' {# @( H
% \: k% s) Y, o+ v) U比如有一个整型数组:
, U/ f( d+ g- d" Y3 V! b- ]/ [1 o" t) {- x7 s2 }5 X
int[] intArray = new int[] {4, 1, 3, -23}; 8 k" S* A/ b+ n! {5 z; j
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
+ ]4 r7 x, F S. v8 J* s( f- |+ n
* x% Q% ] W/ ?2 H7 b( ~9 e# t2 Qimport java.util.*;
" o% x* x- b8 G2 xpublic class Sort{ - \7 ]% I3 X- R3 k$ N! `# z5 A9 I
public static void main(String[] args){
* Q% C& A9 l8 K2 _ int[] intArray = new int[] {4, 1, 3, -23}; 6 k5 K2 r. C0 s: d
Arrays.sort(intArray);
) [: T& ~3 U) l. z } ; V& A$ U4 e* H" z, e+ V9 j; c
}
* k, {8 Y. z; ^: x这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.8 v! m! Q# _6 y5 d% y
0 ?/ w$ g! Z$ @' q/ _如果是字符数组:" l" ]' N- [ C5 ~! Z# a! E; S7 g
, j5 t/ n/ T; K4 J2 e0 `String[] strArray = new String[] {"z", "a", "C"}; 5 n( L* H5 Q" r. }8 H
我们用:
7 E; G0 `; }% N3 H. W6 q8 m/ ?! _9 a. q. h7 x. t9 Z
Arrays.sort(strArray);
1 z; F! [, ]8 }. n {( z进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:
, n; D D. ~% D6 ~ Q3 g
1 t; _. ^! y- j& NArrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
! y; ?+ M& v, w, _当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:% Y& ?2 \ l% @; Q. }5 M) X6 W/ Q% N" s
( A; F1 N2 M5 v+ S0 y* x
Arrays.sort(strArray,0,2); 8 w) o! q$ W7 j9 r4 _
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。$ j/ b+ i* C* s" u# ~7 W
. Q* V7 W: g+ n8 U) e4 d) T
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
# A8 n! q$ F8 x7 E/ S" o- j x) ~7 B7 O
sort(T[] a, Comparator<? super T> c) / ^ m( J; k: M9 t: T
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
0 J+ \/ Y0 I9 e8 P1 w6 [0 S4 Y6 T- H9 R$ V0 n
Arrays.sort(intArray,Comparator.reverseOrder());
9 _/ ?& f1 E8 L1 n' x- M. L这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:# j3 I4 v4 F6 y
+ \7 K( [+ ?" a0 s; t! I. B
Collections.reverse(Arrays.asList(intArray));
! ^# K/ U& G! A/ ^0 R得到该数组的反序。结果同样为4,3,1,-23}。
8 p5 ^3 \- W( Q, f4 B7 q
# B4 g" f) Z5 l) D) D现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:. J# F/ p: Z Z% J j" g
" @, `0 V; C7 l! v% T$ x! P# j* J7 ]class Name implements Comparable<Name>{
3 B$ R) J9 I) ~" N% u6 S$ s public String firstName,lastName;
p/ ?6 x# I _: n4 O) u7 m' u( B public Name(String firstName,String lastName){ ' \* J1 ~8 w: C4 ~! E+ c8 G
this.firstName=firstName;
2 L; P7 N2 ~; W# T( D. A) D2 L" x this.lastName=lastName; ; q, w! M: H/ i3 f; k
} $ C1 {4 e$ S+ E8 u P2 M
public int compareTo(Name o) { //实现接口 . y4 ?& r3 b5 f" Z; P# B
int lastCmp=lastName.compareTo(o.lastName); * f5 ?* y4 o0 `$ o x% M; {6 Z
return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
2 a) h4 V( P3 @ ^) S) } } ! R' t) c: K5 e" W* _! A3 O1 Y
public String toString(){ //便于输出测试
- U$ Q+ b2 k& L: A% q ^' h2 z return firstName+" "+lastName;
0 k9 T! L1 w3 m* x9 v c6 z: e) w } ( f) L9 V3 B" g; [8 G
}
* f8 d1 j9 p$ }1 ^' e这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:( z R# c. M' S& V
3 b+ I9 j" x- t+ b* s j2 M
import java.util.*; 0 Z" U8 ~5 e+ u* c+ Z* j
public class NameSort { 5 [- e7 e# ?8 |4 x. v5 @# g: b
public static void main(String[] args) { 0 r3 E- E/ z5 ] ]6 Q
Name nameArray[] = { * Z" w. }1 T& j
new Name("John", "Lennon"), $ {/ Z2 h9 O( l T* C3 h4 f( \- Z
new Name("Karl", "Marx"),
0 F$ x) r' x% d) Z, P( E new Name("Groucho", "Marx"), & {) A* m& i9 ^+ I
new Name("Oscar", "Grouch") ) E/ D0 V) h7 U! F- U0 N1 h
}; |
|