`

Java_ArrayList_排序

    博客分类:
  • Java
 
阅读更多

via: http://www.importnew.com/17211.html

 

Java ArrayList的不同排序方法

排序字符串对象的 ArrayList

考虑一个 ArrayList 存储着以字符串形式存在的国名(country name),为了对这个 ArrayList 进行排序,你需要调用 Collections.sort()方法,传递由国名构成的 ArrayList 对象。这种方法将按照自然顺序(按字母升序)对元素(国名)进行排序。让我们为此来写一段代码。
SortArrayListAscendingDescending.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package guru.springframework.blog.sortarraylist.ascendingdescending;
 import java.util.ArrayList;
 import java.util.Collections;
 public class SortArrayListAscendingDescending {
 private ArrayList arrayList;
 public SortArrayListAscendingDescending(ArrayList arrayList) {
 this.arrayList = arrayList;
 }
 public ArrayList getArrayList() {
 return this.arrayList;
 }
 public ArrayList sortAscending() {
 Collections.sort(this.arrayList);
 return this.arrayList;
 }
 public ArrayList sortDescending() {
 Collections.sort(this.arrayList, Collections.reverseOrder());
 return this.arrayList;
 }
 }

在上面的类中,我们在构造器中初始化了一个 ArrayList 对象。在 sortAscending()方法中,我们调用了 Collections.sort()方法,并传递这个初始化的 ArrayList对象为参数,返回排序后的 ArrayList。在 sortDescending()方法中,我们调用重载的 Collections.sort()方法让其按照降序对元素排序,这个版本的 Collections.sort()接收ArrayList对象作为第一个参数,一个由 Collections.reverseOrder()方法返回的 Comparator 对象作为第二个参数。我们将会在稍后讲解 Comparator。为了测试排序功能,我们将写一段测试代码。
SortArrayListAscendingDescendingTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package guru.springframework.blog.sortarraylist.ascendingdescending;
 import org.junit.Test;
 import java.util.ArrayList;
 import static org.junit.Assert.*;
 public class SortArrayListAscendingDescendingTest {
@Test
 public void testSortAscendingDescending() throws Exception {
 ArrayList countryList = new ArrayList<>();
 countryList.add("France");
 countryList.add("USA");
 countryList.add("India");
 countryList.add("Spain");
 countryList.add("England");
 SortArrayListAscendingDescending sortArrayList = new SortArrayListAscendingDescending(countryList);
 ArrayList unsortedArrayList = sortArrayList.getArrayList();
 System.out.println("Unsorted ArrayList: " + unsortedArrayList);
 ArrayList sortedArrayListAscending = sortArrayList.sortAscending();
 System.out.println("Sorted ArrayList in Ascending Order : " + sortedArrayListAscending);
 ArrayList sortedArrayListDescending = sortArrayList.sortDescending();
 System.out.println("Sorted ArrayList in Descending Order: " + sortedArrayListDescending);
 }
 }

在上面的测试代码中,我们创建一个 ArrayList 对象,并添加了 5 个字符串对象代表 5 个国家的名字。然后我们调用 getArrayList()、sortAscending()和 sortDescending()方法,并打印这些方法返回的 ArrayList 对象。
输出如下:

-------------------------------------------------------
T E S T S
-------------------------------------------------------  
Running guru.springframework.blog.sortarraylist.ascendingdescending.SortArrayListAscendingDescendingTest  
Unsorted ArrayList: [France, USA, India, Spain, England]
Sorted ArrayList in Ascending Order : [England, France, India, Spain, USA]
Sorted ArrayList in Descending Order: [USA, Spain, India, France, England]  
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec - in guru.springframework.blog.sortarraylis

到目前为止,所要排序的 ArrayList 元素都是非常简单的,我们仅仅只是调用 Collections.sort()方法并传递了需要排序的 ArrayList 对象作为参数。但是更多的是你会遇到一些复杂的情景下对 ArrayList 进行排序。
Collections.sort() 方法对 ArrayList 的元素或者任何其他 List 的实现提供的可比较的元素进行排序,这意味着这些元素的类需要实现 java.lang 包的 Comparable 接口。正如 String 类实现了 Comparable 接口,我们就可以对由国名构成的 ArrayList 排序。有些其他的标准 Java 类实现了 Comparable 接口,包括原始的包装类,例如 Integer、Short、Double、Float、Boolean、BigInteger、BigDecimal、File 和 Date 类都实现了 Comparable 接口。

使用Comparable排序ArrayList

Comparable 是带有单一 compareTo()方法的接口。一个实现了 Comparable 接口的类对象可以与其它同类型的对象进行比较,实现 Comparable 接口的类需要重写 compareTo()方法,这个方法接收一个同类型的对象,并实现这个对象和传递给方法的另一个对象比较的逻辑。compareTo()方法返回Int类型的比较结果,分别代表下面的含义:
正值表示当前对象比传递给 comPareTO()的对象大
负值表示当前对象比传递给 comPareTO()的对象小
零表示两个对象相等
让我们来举一个例子,JobCandidate 类的对象保存在 ArrayList 中并准备对其进行排序。JobCandidate 类有三个成员变量:字符串类型的姓名和性别、整型的年龄。我们想要对保存在 ArrayList 中的 JobCandidate 对象按照年龄进行排序。因此我们要让 JobCandidate 类实现 Comparable 接口并重写 compareTo()方法。
The code of the JobCandidate class is this.
JobCandidate类的代码如下:
JobCandidate.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package guru.springframework.blog.sortarraylist.comparable;
 public class JobCandidate implements Comparable {
 private String name;
 private String gender;
 private int age;
 public JobCandidate(String name, String gender, int age) {
 this.name = name;
 this.gender = gender;
 this.age = age;
 }
 public String getName() {
 return name;
 }
 public String getGender() {
 return gender;
 }
 public int getAge() {
 return age;
 }
 @Override
 public int compareTo(JobCandidate candidate) {
 return (this.getAge() < candidate.getAge() ? -1 :
 (this.getAge() == candidate.getAge() ? 0 : 1));
 }
 @Override
 public String toString() {
 return " Name: " + this.name + ", Gender: " + this.gender + ", age:" + this.age;
 }
 }

在上面 JobCandidate 类被重写的 compareTo()方法中,我们实现了基于年龄的比较逻辑。我见过很多程序员将(this.getAge() – candidate.getAge())作为返回的比较结果。尽管使用这种 return 语句看上去似乎很吸引人,并且也不会对我们的例子造成影响,我的建议是远离这种语句。想象一下,比较整数值,其中有一个或者两个都是负数的结果。这会导致一些错误,让你的程序行为不定,而且更重要的是,这样的错误是很细微的,尤其是在大型的企业应用中很难检测出来。下面我们将写一个辅助类,为委托方对包含了 JobCandidate 元素的 ArrayList 对象进行排序。
JobCandidateSorter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package guru.springframework.blog.sortarraylist.comparable;
import java.util.ArrayList;
 import java.util.Collections;
 public class JobCandidateSorter {
 ArrayList jobCandidate = new ArrayList<>();
 public JobCandidateSorter(ArrayList jobCandidate) {
 this.jobCandidate = jobCandidate;
 }
 public ArrayList getSortedJobCandidateByAge() {
 Collections.sort(jobCandidate);
 return jobCandidate;
 }
 }

在 JobCandidateSorter 类中,我们初始化了一个 ArrayList 对象,委托方将通过构造函数实例化 JobCandidateSorter 。然后我们编写了 getSortedJobCandidateByAge()方法,在这个方法中,我们调用 Collections.sort()并传递已经初始化了的 ArrayList 为参数,最后返回排序后的 ArrayList。
接下来,我们写一个测试类来测试一下我们的代码。
JobCandidateSorterTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package guru.springframework.blog.sortarraylist.comparable;
 import org.junit.Test;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import static org.junit.Assert.*;
 public class JobCandidateSorterTest {
@Test
 public void testGetSortedJobCandidateByAge() throws Exception {
 JobCandidate jobCandidate1 = new JobCandidate("Mark Smith", "Male", 26);
 JobCandidate jobCandidate2 = new JobCandidate("Sandy Hunt", "Female", 23);
 JobCandidate jobCandidate3 = new JobCandidate("Betty Clark", "Female", 20);
 JobCandidate jobCandidate4 = new JobCandidate("Andrew Styne", "Male", 24);
 ArrayList jobCandidateList = new ArrayList&lt;&gt;();
 jobCandidateList.add(jobCandidate1);
 jobCandidateList.add(jobCandidate2);
 jobCandidateList.add(jobCandidate3);
 jobCandidateList.add(jobCandidate4);
 JobCandidateSorter jobCandidateSorter = new JobCandidateSorter(jobCandidateList);
 ArrayList sortedJobCandidate = jobCandidateSorter.getSortedJobCandidateByAge();
 System.out.println("-----Sorted JobCandidate by age: Ascending-----");
for (JobCandidate jobCandidate : sortedJobCandidate) {
 System.out.println(jobCandidate);
 }
 }
 }

在上面的测试类中,我们创建了四个 JobCandidate 对象并把它们添加到 ArrayList,然后传递这个 ArrayList 到构造函数来实例化 JobCandidateSorter 类。最后,我们调用 JobCandidateSorter 类的 getSortedJobCandidateByAge()方法,并打印这个方法返回的排序后的 ArrayList。测试的输出结果如下:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running guru.springframework.blog.sortarraylist.comparable.JobCandidateSorterTest
-----Sorted JobCandidate by age: Ascending-----
Name: Betty Clark, Gender: Female, age:20
Name: Sandy Hunt, Gender: Female, age:23
Name: Andrew Styne, Gender: Male, age:24
Name: Mark Smith, Gender: Male, age:26
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.003 sec
- in guru.springframework.blog.sortarraylist.comparable.JobCandidateSorterTest

使用 Comparable 对 ArrayList 排序是一种常用的方法。但是你必须知道有某些限制。你想要排序的对象的类必须实现 Comparable 并覆写 compareTo()方法。这基本上意味着你将只能基于一个成员变量来比较对象(我们例子中的年龄字段)。如果要求你按照姓名和年龄来对 JobCandidate 对象进行排序怎么办? Comparable 就不是解决的方法了。另外,比较逻辑是需要进行比较的对象的类的一部分,它消除了比较逻辑可复用性的可能。Java 通过使用在 java.util 包下提供的Comparator接口解决了上述的比较需求。

使用 Comparator 排序 ArrayList

Comparator 接口与Comparable 接口相似也提供了一个单一的比较方法叫作 compare()。然而,与 Comparable的 compareTo()方法不同的是,这个 compare()接受两个同类型的不同对象进行比较。
我们将用 Comparator 对我们之前使用过的相同 JobCandidate 类对象进行排序。我们将通过实现 Comparatoras 匿名内部类,允许对 JobCandidate 对象按照年龄和姓名进行排序。
下面是使用了 Comparator 的 JobCandidate 类代码
JobCandidate.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package guru.springframework.blog.sortarraylist.comparator;
 import java.util.Comparator;
 public class JobCandidate {
 private String name;
 private String gender;
 private int age;
 public JobCandidate(String name, String gender, int age) {
 this.name = name;
 this.gender = gender;
 this.age = age;
 }
 public String getName() {
 return name;
 }
 public String getGender() {
 return gender;
 }
 public int getAge() {
 return age;
 }
 public static Comparator ageComparator = new Comparator() {
 @Override
 public int compare(JobCandidate jc1, JobCandidate jc2) {
 return (jc2.getAge() < jc1.getAge() ? -1 :
 (jc2.getAge() == jc1.getAge() ? 0 : 1));
 }
 };
 public static Comparator nameComparator = new Comparator() {
 @Override
 public int compare(JobCandidate jc1, JobCandidate jc2) {
 return (int) (jc1.getName().compareTo(jc2.getName()));
 }
 };
 @Override
 public String toString() {
 return " Name: " + this.name + ", Gender: " + this.gender + ", age:" + this.age;
 }
 }

在上面的类中,从 29 行到 35 行,我们写了一个匿名类并实现了 compare()方法,按照年龄的降序对 JobCandidate 对象进行排序。从37行到42行,我们又写了一个匿名类并实现了 compare() 方法,按照姓名的升序对 JobCandidate进行排序。现在我们写一个类,为委托方对 ArrayList 的元素进行排序。
JobCandidateSorter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package guru.springframework.blog.sortarraylist.comparator;
 import java.util.ArrayList;
 import java.util.Collections;
 public class JobCandidateSorter {
 ArrayList jobCandidate = new ArrayList<>();
 public JobCandidateSorter(ArrayList jobCandidate) {
 this.jobCandidate = jobCandidate;
 }
 public ArrayList getSortedJobCandidateByAge() {
 Collections.sort(jobCandidate, JobCandidate.ageComparator);
 return jobCandidate;
 }
 public ArrayList getSortedJobCandidateByName() {
 Collections.sort(jobCandidate, JobCandidate.nameComparator);
 return jobCandidate;
 }
 }

在上面的类中,我们写了 getSortedJobCandidateByAge()方法,在这个方法内部我们调用了 Collections.sort()的重载版本,这个版本传递要被排序的 ArrayList 对象和比较年龄的 Comparator 对象。在 getSortedJobCandidateByName()方法内部,我们又调用了 Collections.sort()的另一个重载版本,这个版本传递要被排序的 ArrayList 对象和比较姓名的 Comparator 对象。
Let’s write a test class to test our code.
让我们写一个测试类来测试我们的代码。
JobCandidateSorterTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package guru.springframework.blog.sortarraylist.comparator;
 import guru.springframework.blog.sortarraylist.comparator.JobCandidate;
 import guru.springframework.blog.sortarraylist.comparator.JobCandidateSorter;
 import org.junit.Before;
 import org.junit.Test;
 import java.util.ArrayList;
 import static org.junit.Assert.*;
 public class JobCandidateSorterTest {
 JobCandidateSorter jobCandidateSorter;
 @Before
 public void setUp() throws Exception {
 JobCandidate jobCandidate1 = new JobCandidate("Mark Smith", "Male", 26);
 JobCandidate jobCandidate2 = new JobCandidate("Sandy Hunt", "Female", 23);
 JobCandidate jobCandidate3 = new JobCandidate("Betty Clark", "Female", 20);
 JobCandidate jobCandidate4 = new JobCandidate("Andrew Styne", "Male", 24);
 ArrayList jobCandidateList = new ArrayList&lt;&gt;();
 jobCandidateList.add(jobCandidate1);
 jobCandidateList.add(jobCandidate2);
 jobCandidateList.add(jobCandidate3);
 jobCandidateList.add(jobCandidate4);
 jobCandidateSorter = new JobCandidateSorter(jobCandidateList);
 }
@Test
 public void testGetSortedJobCandidateByAge() throws Exception {
 System.out.println("-----Sorted JobCandidate by age: Descending-----");
ArrayList sortedJobCandidate = jobCandidateSorter.getSortedJobCandidateByAge();
 for (JobCandidate jobCandidate : sortedJobCandidate) {
 System.out.println(jobCandidate);
 }
 }
@Test
 public void testGetSortedJobCandidateByName() throws Exception {
 System.out.println("-----Sorted JobCandidate by name: Ascending-----");
ArrayList sortedJobCandidate = jobCandidateSorter.getSortedJobCandidateByName();
 for (JobCandidate jobCandidate : sortedJobCandidate) {
 System.out.println(jobCandidate);
 }
 }
 }

在测试类中我们向 ArrayList 中添加若干 JobCandidate 对象,并使用 Before 注释在测试单元的 setup()方法中创建了一个 JobCandidateSorter 对象。如果你是一个 Junit 新手,可以参考我以前的文章包括 Junit 注释(Junit 单元测试系列)。在 testGetSortedJobCandidateByAge()测试方法中我们调用了 getSortedJobCandidateByAge()方法,并打印了该方法返回的排序后的 ArrayList。在 testGetSortedJobCandidateByName()测试方法中我们调用了getSortedJobCandidateByName()方法并同样打印该方法返回的 ArrayList。测试的输出如下:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running guru.springframework.blog.sortarraylist.comparator.JobCandidateSorterTest
-----Sorted JobCandidate by name: Ascending-----
Name: Andrew Styne, Gender: Male, age:24
 Name: Betty Clark, Gender: Female, age:20
 Name: Mark Smith, Gender: Male, age:26
 Name: Sandy Hunt, Gender: Female, age:23
-----Sorted JobCandidate by age: Descending-----
Name: Mark Smith, Gender: Male, age:26
 Name: Andrew Styne, Gender: Male, age:24
 Name: Sandy Hunt, Gender: Female, age:23
 Name: Betty Clark, Gender: Female, age:20
 Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.023 sec
- in guru.springframework.blog.sortarraylist.comparator.JobCandidateSorterTest

总结

在本文中我们看到了 ArrayList 排序的不同方法。一种是使用 Comparable 另一种是使用 Comparator。方法的选择一直是造成程序员们困惑的原因之一。你最应该记住的就是一个 Comparable 对象可以说“我可以自己与另外一个对象比较”而一个 Comparator 对象可以说“我可以比较两个不同的对象”。你不能说一个接口比另一个要好。选择的接口取决于你需要实现的功能。

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    JavaMap.rar_arraylist map_collection_java map_javamap_地图 java

    Java Map集合类是Java编程语言中用于存储键值对数据结构的重要接口,它与ArrayList、LinkedList等属于Java集合框架的一部分。在Java中,Map接口不继承Collection接口,而是独立存在,因为它代表的是键值对(key-...

    JSP_使用_Session_ArrayList_实现购物车程序

    根据给定的信息,本文将详细解释如何在Java Server Pages (JSP)中使用`HttpSession`和`ArrayList`来实现一个简单的购物车程序。本文主要分为以下几个部分:商品类(`Goods`)的设计、购物车功能实现的具体步骤、以及...

    java中对ArrayList进行排序

    java中对ArrayList进行排序的方法参考

    Java ArrayList实现的快排,归并排序,堆排序

    ArrayList作为Java集合框架中的一员,它提供了丰富的操作接口,包括对元素的添加、删除、修改以及排序等。本篇将重点讲解如何利用ArrayList实现快速排序(Quick Sort)、归并排序(Merge Sort)和堆排序(Heap Sort...

    demo-java.rar_DEMO_deom java_拓扑 Java_拓扑图

    3. 拓扑排序:在某些场景下,为了理解数据流或执行顺序,可能需要对拓扑图进行排序。Java 提供的图算法库可以帮助实现这一点,例如使用深度优先搜索(DFS)或广度优先搜索(BFS)算法。 4. 动态更新:在电信系统中...

    Java 对象排序详解.rar_java 对象排序_对象_排序

    总的来说,Java提供了多种方式对对象进行排序,包括ArrayList的`Collections.sort()`,HashSet的转换和排序,以及TreeSet的自然排序和Comparator排序。理解这些机制可以帮助我们更好地控制数据结构的排序行为,从而...

    Java_javabus_java_

    ArrayList或LinkedList可用于存储车辆,HashMap或TreeMap可用于快速查找和排序。 6. 多线程(Multithreading):为了让公交车能同时进行行驶、到站等动作,可能需要使用多线程技术。例如,每个公交车可以作为一个...

    代码java_java_

    6. **数据结构与算法**:可能涉及到排序、查找等算法,比如使用Collections.sort()对宿舍信息进行排序。 7. **异常处理**:在处理文件操作时,通常需要捕获并处理IOException等异常,确保程序的健壮性。 8. **项目...

    Java_索引解说,Java_索引解说,Java_索引解说,Java_索引解说

    Java中的索引并非像SQL数据库那样直接应用于数据结构,但在Java编程中,索引的概念经常出现在数据结构和算法中,特别是在处理数组、列表和其他集合类时。例如,当我们遍历数组或列表时,索引是一个整数,用于标识...

    arrayList排序

    - 对于大量数据的排序,ArrayList的性能可能不如使用LinkedList,因为ArrayList排序时涉及到大量的索引计算和元素移动。 - 如果ArrayList中元素的类型不一致,`Collections.sort()`会抛出ClassCastException异常,...

    java_function_Search.rar_function search()_java Functi_java func

    例如,在`java.util.ArrayList`或`java.util.LinkedList`类中,`search()`可能表示查找指定元素的索引;而在`java.util.Collections`类中,可能会有一个静态的`binarySearch()`方法,用于对排序好的列表进行二分搜索...

    java对ArrayList排序代码示例

    然而,ArrayList本身并不提供排序功能,但我们可以借助Java的Collections类提供的sort()方法来实现排序。本文将通过三个示例详细讲解如何在Java中对ArrayList进行排序。 首先,我们来看一个简单的例子,创建一个名...

    Java_100examples.rar_Java 100例_Java_100examples.rar_java 100例

    3. **集合框架**:如ArrayList、LinkedList、HashSet、HashMap等的使用,以及迭代器、泛型的理解。 4. **异常处理**:学习如何捕获和处理运行时错误,如try-catch-finally语句。 5. **输入/输出**:I/O流的概念,...

    H马Java面试专题课

    │ 10-冒泡排序_初步实现.mp4 │ 13-冒泡排序_优化_进一步优化比较次数.mp4 │ 17-选择排序_实现.mp4 │ 18-选择排序_vs_冒泡排序.mp4 │ 19-插入排序_演示.mp4 │ 22-希尔排序_演示.mp4 │ 25-快速排序_单边...

    JAVA_API_1.7中文 完整高清版 CHM版

    - **多路归并排序**:在`java.util.Arrays`和`java.util.Collections`中增加了多路归并排序算法,提高了大规模数据的排序效率。 - **字符串inswitch**:在switch语句中可以直接使用字符串,增强了代码的可读性和...

    java_code.rar_java code

    在算法方面,Java代码实例可能包含了排序算法(如冒泡排序、快速排序、归并排序)、查找算法(如二分查找)以及其他常见问题的解决方案,如字符串匹配、图论问题等。这些实例有助于提升编程能力和问题解决能力。 ...

    MLDN魔乐JAVA_13链表.MLDN魔乐JAVA_13链表.rar

    在Java中,链表主要通过两种方式实现:LinkedList类和ArrayList类。ArrayList基于动态数组,而LinkedList基于链表。LinkedList类实现了List接口,提供了丰富的链表操作方法,如add、remove、get等。 5. 链表的优点...

    LeetCode_Java_Solutions

    在LeetCode_Java_Solutions中,你会遇到各种算法,包括排序(快速排序、归并排序、插入排序等)、搜索(二分查找、深度优先搜索、广度优先搜索等)、动态规划、贪心算法、回溯法等。这些算法是编程竞赛和面试中经常...

    knn.zip_KNN java_classification java_java KNN_knn_knn分类

    - **数据结构**:在Java中,可以使用数组或集合(如ArrayList、LinkedList)存储样本数据,每个样本为一个对象,包含特征和对应的类别。 - **距离计算**:编写函数计算两个样本之间的距离,如欧几里得距离公式:`...

    java40samples_java_40_

    此外,多维数组和动态数组(ArrayList)的使用也是常见的主题。 3. **数据结构**:数据结构是组织和存储数据的方式,如栈、队列、链表、树和哈希表等。这些实例可能会演示如何在Java中实现这些数据结构,并展示它们...

Global site tag (gtag.js) - Google Analytics