TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
) ?3 T/ j4 b4 C- N- z1 a7 x
6 Y. D3 _# X2 p, j首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
V( Y3 O! I( _: B5 r) Z- a c# u4 |" Q' C4 y6 n
例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。
# R, i8 {6 m, E, @! }8 n: U- W+ E
5 l% u* a5 m' K对数组进行排序1 O! l/ D' {% `/ i7 j3 z4 x
+ T" k- k9 V: d3 F& L, A比如有一个整型数组:/ }9 v8 K% y5 D P6 @$ W
1 a( d% D8 h- k) K0 b
int[] intArray = new int[] {4, 1, 3, -23};
( b' f9 N# \6 D% u2 u我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
- w- w+ }4 `8 ~9 |+ r1 K9 _* R6 o8 B/ Y: d$ ]! C
import java.util.*; / a( r4 ?; i7 R* Q8 Q
public class Sort{ ' x4 u6 x+ B& T0 U' I( ^4 h7 e) h
public static void main(String[] args){ ( P; f* Z/ H& E
int[] intArray = new int[] {4, 1, 3, -23}; ! p; s: \' i I! `3 o, i1 I" ~
Arrays.sort(intArray); 0 z- j& N# i6 r" l
}
+ [* v& X% C) ^* |8 h2 B} 1 r Q2 H* F/ ?, b: {' h
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}., U& _- Z! H: {8 L9 g' u, O
- C# H$ ~: F4 w% p如果是字符数组:
) R& ~: _5 q5 C, J0 Z+ F. x3 v2 l8 s; A( Z/ |
String[] strArray = new String[] {"z", "a", "C"}; ' ]/ ^" a/ P9 [+ g* {. I
我们用:. ^7 o3 Q p( g/ M0 r$ |7 _
5 D+ U4 ]# V0 t# ]( o9 W
Arrays.sort(strArray);
: i* w% `0 o- _4 y, [! ^( ~' @进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:
& j! T4 @' B: f4 u7 T' ? x9 e4 H7 M5 T/ I/ N0 R
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
7 n2 y, p. \+ v8 b当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:" v2 |: x7 X+ l5 ~- P* g4 O
8 o" c6 Z" ]) Z; i5 @Arrays.sort(strArray,0,2);
0 a8 g$ T( ~- H; f7 P5 l这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。5 [9 R# k. L {# i( o! X
* H) y3 z% T& [" c当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
" s1 l0 T1 R8 r/ z, ~: q! a$ O4 b$ E" v
sort(T[] a, Comparator<? super T> c) : y2 X9 T+ P; }! ]+ D
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:( T, I+ h4 Z% m F/ ?
s9 @. c3 s& F2 y
Arrays.sort(intArray,Comparator.reverseOrder()); 9 s0 O( Y( q g$ ]
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:# I: A1 P) ?+ q# o5 v# i! _7 J$ {
) _& U7 v6 o+ y/ |; u
Collections.reverse(Arrays.asList(intArray));
3 Y) M0 o( \1 H" ^; M# {4 W得到该数组的反序。结果同样为4,3,1,-23}。
5 J1 L" s+ E1 i+ ^1 P9 p
6 `0 W( X& n8 ?) l现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:2 S5 Y6 P9 b( A/ S5 H
, v5 o1 [0 l' l2 l# @! h) N! H
class Name implements Comparable<Name>{ # R+ R8 [5 k* s- P
public String firstName,lastName;
. R/ }+ x1 m1 q- A) ?2 } public Name(String firstName,String lastName){ + m S. V5 \+ O/ s% }1 D
this.firstName=firstName; 4 _# i. q, g5 R S# `0 O
this.lastName=lastName; , H9 X2 Q% j1 B4 q, u( k8 _
} 0 w9 `' V0 x+ |/ x8 h$ Z+ J
public int compareTo(Name o) { //实现接口 4 y7 L2 f/ h; W7 p- |
int lastCmp=lastName.compareTo(o.lastName);
3 j1 V- y& a% |4 H' a return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
j4 ], ~. s. g; ]; ~) ^ } $ T4 v- }7 Y4 L C! ~# S
public String toString(){ //便于输出测试 ' O2 B4 D9 D& s
return firstName+" "+lastName;
$ b" c2 X. p/ r' b1 p; c2 Z7 F } + H3 h0 N$ P5 V/ D& c/ X& O& E
} " h7 c+ N/ [' B1 _
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:6 [0 N8 K8 b# v5 F
4 ?( d: M" U( ?9 X, s& {' G5 A" z# { import java.util.*; # k. U! U* a+ ~9 v$ G
public class NameSort {
7 r; x/ W4 v; t" t public static void main(String[] args) {
l7 y- L1 f, u+ e8 z( O2 K. L. {8 k1 G Name nameArray[] = { , B. A! @3 c! n( ^9 Y. P$ i& K K
new Name("John", "Lennon"),
; Q9 _0 i6 N+ a+ S4 ~/ n9 }1 M3 L new Name("Karl", "Marx"), 4 W" \% E9 t( j, H! `2 Y, z! }
new Name("Groucho", "Marx"),
$ @) K J0 x/ X& j& s new Name("Oscar", "Grouch")
( S U' p! B+ c" ]/ j1 _ w; s }; |
|