TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
$ |0 g( s, b& ^4 E( i1 G; Y+ f7 ^( \, l5 u% ]# i+ r
首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
2 F. ]3 u. D! F! a& |7 k1 R& X9 q5 E5 c9 Q4 G4 z
例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。
( R& j0 n3 V. o. H
7 B( {9 i# c/ e- q& D" }对数组进行排序0 B0 O$ m h' Y# e: j, R
" i0 e( q. r5 i% S1 i
比如有一个整型数组:0 K. F! `5 K [ ~3 C- D
9 C8 e# N- A8 k9 w9 F
int[] intArray = new int[] {4, 1, 3, -23};
5 \( o8 K" C% \我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:9 c% Q: f# w+ E' t/ x. X
* b( a, N/ X) z# A; e% h
import java.util.*; / T$ f6 S+ q$ o- z0 i8 M8 s
public class Sort{ / C9 C/ k5 f* S' \. V8 \
public static void main(String[] args){
8 X& p5 O3 O# D. w, T, U- q0 r6 G9 h, x int[] intArray = new int[] {4, 1, 3, -23};
- D0 d6 n7 a5 V: h' [$ i6 X5 _ Arrays.sort(intArray); ; T, w' x8 z1 w. {1 S3 G" p
}
- M8 ~6 \+ m- W8 e6 q! @$ t' t} 6 c" U9 J6 T/ i' u' ~
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.
7 ]$ ?! ~+ C( N: [3 j! I" u4 s ?$ Y
8 C: w* I, L* j4 ` J E如果是字符数组:$ x a4 b' V' K1 \
1 E1 }! ]% I |9 q E2 E9 JString[] strArray = new String[] {"z", "a", "C"}; # J* O6 s2 q2 _
我们用:
8 S+ r( }8 \+ D4 j
' W6 o3 j4 P6 T) C' j) \" W, l8 Q4 j- @Arrays.sort(strArray);
% q( O! N8 z" L" O9 u进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:# h1 X+ \5 Q( Y% J0 u
) a$ a- N3 ^+ h% {! }0 ]Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); * }6 \3 b8 [7 j2 M1 m
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
, Y0 c) h S; r% v. c0 w
6 f) |* k* a- n+ JArrays.sort(strArray,0,2); ! j+ d; z0 r6 x4 k9 t c
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。2 S2 @0 k% Y& o2 [
' n5 n5 Q8 {% A6 I: Y2 n
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
' D0 ?/ y: L) }9 V1 T
8 m' i4 l0 F! S/ I# csort(T[] a, Comparator<? super T> c)
- H$ R; I* w% K我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:4 G5 ?( A& `% P6 t
2 l4 Z/ I8 V$ k
Arrays.sort(intArray,Comparator.reverseOrder());
: |* H8 }7 m/ E7 f7 F! r+ F这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:- T% y$ Z$ O4 L) n
. g7 _2 G3 K, t# _( K+ i
Collections.reverse(Arrays.asList(intArray)); & }+ J& ^/ i1 _1 N+ p1 i2 h, k: c
得到该数组的反序。结果同样为4,3,1,-23}。
% d- x- A7 W* Z, K
9 r: @" I5 V9 L2 L0 p现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
i0 E2 K2 ]" m: C0 u! v9 ?" H6 z6 E3 I
class Name implements Comparable<Name>{
; x m, e' R X$ I P public String firstName,lastName; + F- [% c: _7 x4 U3 p/ X
public Name(String firstName,String lastName){
8 r) _% D9 I0 e# L3 i this.firstName=firstName;
5 {. l. p2 K; l2 e* a7 L this.lastName=lastName;
- s7 r3 K! K; S; t* y5 h } . g+ v/ g+ b3 f$ n' e% D9 a/ B
public int compareTo(Name o) { //实现接口
5 v1 k/ t$ n P% S int lastCmp=lastName.compareTo(o.lastName); ; x& B0 G5 J1 E* p
return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
( V+ U$ p, H5 O$ T* E4 L } # y/ ^2 t2 K4 Z" M
public String toString(){ //便于输出测试 ; o- |. S' Z5 K! N5 m5 K
return firstName+" "+lastName;
2 {/ u+ d# {3 ^7 u. F } }6 \ m# @9 S8 ^
}
) K& ^3 w1 k4 X K! M9 r9 y: b这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
: g5 B3 r! k7 ~/ Y
4 n% y4 Y5 J. C8 j0 P, X: y2 j' h import java.util.*;
4 ~5 Z. E( \8 \, E8 O- k# N& z9 O: R public class NameSort {
+ ]1 I3 b) n5 L3 o public static void main(String[] args) { - s. h& z9 S7 f' [% J; X9 j
Name nameArray[] = {
. B2 ~( w6 Z/ h+ d, [0 G new Name("John", "Lennon"), 9 A! s- j2 Y" G3 ]) K5 g
new Name("Karl", "Marx"), - k! ^5 C p4 H5 Q1 z1 t
new Name("Groucho", "Marx"), " ?0 h( x3 y+ G; x0 ]3 k0 V5 |% e
new Name("Oscar", "Grouch") # U7 J& C+ d- r. T( u. {' u" D
}; |
|