TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
: w1 b" x# B: o9 [; z
( C, S# D5 C( x1 n a- q! l首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
: c6 E8 F8 M+ a; ?, K! n3 q- J
% j# ?& c2 m3 [2 z例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。7 ?2 b. t9 P3 M; _( q, v; m
1 t2 F N$ N; e, R对数组进行排序/ c0 ?3 e% M, G C! x/ ]5 f9 a( {9 ~
" Y! l5 z; K; Y& j
比如有一个整型数组:
2 Q+ n8 E; |: C1 F* ~0 N `1 u0 B( o- {& w
int[] intArray = new int[] {4, 1, 3, -23}; , `$ p @& G Y- @
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
- b$ s) Z! |; {, g" f n3 C% i i, i4 {9 B. J# z5 P( S b
import java.util.*;
6 \2 g5 I: J! ?. \- ]" Kpublic class Sort{ , a) D! {; `, L1 D# V6 }
public static void main(String[] args){ ' J# A5 X5 [. |6 b
int[] intArray = new int[] {4, 1, 3, -23}; * X$ J Y% w8 ]0 v0 y
Arrays.sort(intArray);
" A. ^/ X4 `$ ?& D- l8 W, r } 6 |' X5 C; E7 l; U) k* P
}
# ]$ i8 S+ Q q% B, }2 I ~9 G这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.3 k1 V2 e0 ~% i( r
" `3 s, L9 G# o; `: }3 B; H- d/ d! d
如果是字符数组:
& ~+ d& y- R3 K e! ~' d+ b5 {9 X4 ^ g4 m: W9 f; ]% o' {0 e. E5 r
String[] strArray = new String[] {"z", "a", "C"};
: }' d# X* |- Q( E [" n. @1 k我们用:
. H1 P- x$ y- n0 N% i* u" b; ~6 k5 b8 K
Arrays.sort(strArray);
; p* C2 _4 M3 H+ O$ V进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写: _/ x" a" C6 f0 l. ]
3 {- r1 q& |* ]
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
- p8 S% W V3 y+ D: U e& L当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
: Z% B5 d3 C4 P% l6 v2 [
% V- D6 K1 h) b' h! t/ tArrays.sort(strArray,0,2); " u2 }3 _, d8 l$ {1 z; f
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
2 g4 ~, c+ @6 V I, e7 J6 O2 {, \ j# l
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个$ d5 s3 X$ V; R% S* w
0 `' r! M2 e- z4 Ssort(T[] a, Comparator<? super T> c) 3 G! d6 @% y+ D
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
& p4 I5 }7 K+ L1 O9 f3 s9 {5 q' H& M$ g
Arrays.sort(intArray,Comparator.reverseOrder());
* s8 h, Y0 ?8 [; S; l9 o) A这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:
8 I& ~# ?: |' c& g! X+ q
+ E, ~; A+ p9 B a4 gCollections.reverse(Arrays.asList(intArray));
4 Y2 U7 V F! N* o; _8 H得到该数组的反序。结果同样为4,3,1,-23}。# r3 s' V# i4 {: G6 d. l6 F( Z6 [
4 ^; E) d7 H0 t2 U/ b2 M5 `" J3 m现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
) u, O5 y+ j: s# M
% o, ^; P% u2 w9 U8 _3 gclass Name implements Comparable<Name>{
a& j3 A$ N7 a public String firstName,lastName; 8 p/ n) k4 i5 u! A9 S v& A
public Name(String firstName,String lastName){ 2 o" S L7 z8 |, s& ]2 Q' a
this.firstName=firstName;
" p5 C% o X* s8 @* L this.lastName=lastName; 8 ]! q, [3 A4 W+ b( ^! H
}
/ x) S% r. B% D; z7 s. F+ I2 w public int compareTo(Name o) { //实现接口
/ Z$ V0 m; {3 B8 R* L int lastCmp=lastName.compareTo(o.lastName);
) F v" B3 f Y- i6 o return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); 5 N+ i) r4 k8 P7 \& t% y) q
}
1 h( k* R! O8 }9 n: f public String toString(){ //便于输出测试 ) h& o0 C$ Y( e4 h2 w- z+ @1 _; r* }
return firstName+" "+lastName;
y2 O9 x% K) d8 q! [* ^ } 0 x$ v: Z2 _% `4 M
}
; J4 P: v- J, O5 ]* w d o这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:( I- c; {, F5 b; {/ O4 S
& p) b; ^& ~5 ^/ N3 R, Z6 W
import java.util.*; , n2 @ c% Q- ^% m) G/ Z
public class NameSort { 5 `, T7 f- m: v+ u. X, b2 D
public static void main(String[] args) {
8 n3 }+ n# E; M Name nameArray[] = { + s A+ N/ Y7 e1 P
new Name("John", "Lennon"),
' Q$ P2 Y* D/ j( ]2 Y- e% c! ^& W new Name("Karl", "Marx"), ) ]1 s4 r; h1 U3 ~0 w: @( S
new Name("Groucho", "Marx"), 3 e: @2 Z+ y1 e; _; f( `9 P
new Name("Oscar", "Grouch")
* L3 I( z1 u8 d: L5 E, e, e }; |
|