TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
# N7 g" @* t: p a. g8 C- x! Z5 |8 e$ I
首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。* q1 @# U! G$ J1 k8 B* a5 |. w
: a, t0 I0 `4 v5 L$ z
例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。# n8 v' O# k0 W' Q( D9 W# X' Q6 D
: W0 G" ~0 B% J+ w; o对数组进行排序
$ s- K6 a; X, @* Y7 S8 i6 x8 P: ~4 ]# d
比如有一个整型数组:4 n5 V, j8 M4 y7 n- Z; i9 w
( U* ?% [% }8 D7 j- [ \3 N8 Jint[] intArray = new int[] {4, 1, 3, -23};
( R& x6 f3 T0 o% H我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
N9 @# P. q3 j# |/ _2 z9 X+ ?# d' A- Y# m2 C
import java.util.*;
6 a( P0 p. _9 L, a$ I0 Y/ Ipublic class Sort{
- ^8 [6 ?, ]* A) ? public static void main(String[] args){
- F, L3 q, @5 G ?, j$ V3 e$ Y0 ^ int[] intArray = new int[] {4, 1, 3, -23}; 6 K5 w; j0 Q6 z- f+ N
Arrays.sort(intArray);
, h w$ j4 t9 n; {+ j2 a1 W }
Q9 @. x) }7 @} 6 H- g: h z; d
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.$ R% L+ D) o2 g- F
, ]/ P# D0 T3 R. b
如果是字符数组:. p( s9 B; K( u" U5 |' [
% f9 \9 o! I k! n
String[] strArray = new String[] {"z", "a", "C"}; 2 d) q# c/ \- ]/ }2 f4 @
我们用:
6 ]8 L8 P x1 o, m! A4 ]1 I Z$ i6 [7 J$ q8 p# K
Arrays.sort(strArray);
1 R0 s' P- B* A+ ~6 g" V) g9 ^" T进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:: I h, O0 B! a& U3 y7 a" a9 g: Z
8 y) Q4 \/ j. z; gArrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); - e7 ?% ^+ h* J! S& t' }7 ^1 @% X
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
- q5 N3 a2 V: x q
! J4 t% L, A7 u# O6 @Arrays.sort(strArray,0,2);
5 b) `' ]4 Z5 p这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
) r% {% [; U7 ]& o
2 \& {5 t4 l3 j当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
6 e( E( z1 A. Q* H+ u9 b' b6 x" F* n! x
sort(T[] a, Comparator<? super T> c) 3 c/ o0 m1 R$ b3 `
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
[! A+ }: u- g# i& M& t- i; t
, r. \( o) k2 s, @Arrays.sort(intArray,Comparator.reverseOrder()); * p6 b4 a& |' ?, c6 l: f
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:6 u3 F4 ^7 h; ^2 r! Y1 S* [
# U- w7 [; E/ J( C' D
Collections.reverse(Arrays.asList(intArray)); 8 A9 w' n6 n9 `3 e
得到该数组的反序。结果同样为4,3,1,-23}。& l. C! @$ D0 e( K( p1 m7 L
Q$ \$ }7 e) n, }5 P) W7 U现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
7 E; n) @6 l% N" S8 Z8 N: t; B* t' P! j3 B4 m- m9 @4 I5 t/ [
class Name implements Comparable<Name>{ $ L' W+ \9 [# R
public String firstName,lastName; A, L* ^1 h* S! s+ g A
public Name(String firstName,String lastName){
% [4 j4 y- x/ q Y2 A; ? this.firstName=firstName;
. p% |/ z; B5 N$ D this.lastName=lastName;
3 k" I" ]2 d+ c' x( x G }
$ Z5 h4 ]2 P' n, u; C/ K4 |7 F+ L public int compareTo(Name o) { //实现接口 4 k+ L/ \& V: Q c v. X# u# \" I6 q
int lastCmp=lastName.compareTo(o.lastName); 5 l4 |8 {) T, B- y
return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); & o. n/ m7 t7 X" I3 t% Z* `
} ) V/ ^5 [; [5 O& Y3 k) l) ^8 {
public String toString(){ //便于输出测试
) c- U3 Z8 v& A' n return firstName+" "+lastName; 6 S+ _! c5 L2 k# N4 B- g; t3 W4 n
} * F. r' k7 U: r' f% b7 H
}
+ b8 y' n ?& A这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
# X% ]- m! H7 y' l N# t7 U$ o4 C: K0 _" a, Y( D
import java.util.*;
& }" n! \2 o6 S' [; h: C public class NameSort {
- v; V( \ k7 \) y; t( V public static void main(String[] args) {
& \& a$ k0 D7 N# W" ? Name nameArray[] = { ) Z% E2 V, ^1 L) n
new Name("John", "Lennon"),
& j- J' ~- ^2 \- M+ w( ` new Name("Karl", "Marx"), 4 }& ^1 X1 _( y& A( u0 X" x0 o" ?
new Name("Groucho", "Marx"), . K. ]: _6 b; W) Z0 H, g0 f
new Name("Oscar", "Grouch")
& u' p2 ^+ u4 i- d0 m }; |
|