API文档 => java.util => List,Map,Set

概念:
Java中的集合是工具类,可以存储任意数量的具有共同属性的对象

场景:

  • 无法预测存储数据的数量
  • 同时存储具有一对一关系的数据
  • 需要进行数据的增删
  • 数据重复问题

集合框架的体系结构:
Collection:类的对象,Map:键值对
image.png

List(列表)

  • List是接口
  • List是元素有序并且可以重复的集合,称为序列
  • List可以精确的控制每个元素的插入位置,或删除某个元素的位置
  • List的两个主要实现类是ArrayList和LinkedList

ArrayList

由于ArrayList用的比较多,所以接下来主要说明ArrayLsit

  • ArrayList底层由数组实现
  • 动态增长,以满足应用程序的需求
  • 在列表尾部插入或删除数据非常有效
  • 更适合查找和更新元素
  • ArrayList中的元素可以为null

    在List中操作字符串

    ```java package com.song.test;

import java.util.ArrayList; import java.util.List;

public class TryDemoOne {

  1. public static void main(String[] args) {
  2. // 用ArrayList存储编程语言的名称,并输出
  3. List list = new ArrayList();
  4. list.add("Java");
  5. list.add("C");
  6. list.add("C++");
  7. list.add("Go");
  8. list.add("swift");
  9. // 输出列表中元素的个数
  10. System.out.println("列表中元素的个数为:" + list.size());
  11. // 遍历输出所有的编程语言
  12. for (int i = 0; i < list.size(); i++) {
  13. System.out.print(list.get(i) + ",");
  14. }
  15. System.out.println();
  16. // 移除列表中的C++
  17. list.remove(2);
  18. for (int i = 0; i < list.size(); i++) {
  19. System.out.print(list.get(i) + ",");
  20. }
  21. System.out.println();
  22. // 移除列表中的Go
  23. list.remove("Go");
  24. for (int i = 0; i < list.size(); i++) {
  25. System.out.print(list.get(i) + ",");
  26. }
  27. System.out.println();
  28. // 判断list中是否包含"Java"字符串
  29. System.out.println(list.contains("Java"));
  30. }

}

  1. <a name="glXsn"></a>
  2. #### 在List中操作自定义对象
  3. Notice.java
  4. ```java
  5. package com.song.test;
  6. import java.util.Date;
  7. public class Notice {
  8. private int id;
  9. private String title;
  10. private String creator;
  11. private Date createTime;
  12. public Notice(int id, String title, String creator, Date createTime) {
  13. super();
  14. this.id = id;
  15. this.title = title;
  16. this.creator = creator;
  17. this.createTime = createTime;
  18. }
  19. ...get,set方法...
  20. }

NoticeTest.java

  1. package com.song.test;
  2. import java.util.ArrayList;
  3. import java.util.Date;
  4. public class NoticeTest {
  5. public static void main(String[] args) {
  6. // 创建Notice类的对象,生成三条公告
  7. Notice notice1 = new Notice(1, "欢迎来到我的教室", "管理员", new Date());
  8. Notice notice2 = new Notice(2, "请同学们按时提交作业", "老师", new Date());
  9. Notice notice3 = new Notice(3, "考勤通知", "老师", new Date());
  10. // 添加公告
  11. ArrayList noticeList = new ArrayList();
  12. noticeList.add(notice1);
  13. noticeList.add(notice2);
  14. noticeList.add(notice3);
  15. // 显示公告
  16. for (int i = 0; i < noticeList.size(); i++) {
  17. System.out.println(i + 1 + ":" + ((Notice) noticeList.get(i)).getTitle());
  18. }
  19. // 在第一条公告后面添加一条新公告
  20. Notice notice4 = new Notice(4, "在线编辑器可以使用啦!", "管理员", new Date());
  21. noticeList.add(1, notice4);
  22. System.out.println("*********************************");
  23. for (int i = 0; i < noticeList.size(); i++) {
  24. // 注意这里需要强制类型转换为Notice类,否则无法调用getTitle()
  25. System.out.println(i + 1 + ":" + ((Notice) noticeList.get(i)).getTitle());
  26. }
  27. // 删除按时完成作业的公告
  28. noticeList.remove(2);
  29. System.out.println("*********************************");
  30. for (int i = 0; i < noticeList.size(); i++) {
  31. System.out.println(i + 1 + ":" + ((Notice) noticeList.get(i)).getTitle());
  32. }
  33. // 修改第二条公告的title
  34. notice4.setTitle("Java在线编辑器可以使用了");
  35. System.out.println("*********************************");
  36. for (int i = 0; i < noticeList.size(); i++) {
  37. System.out.println(i + 1 + ":" + ((Notice) noticeList.get(i)).getTitle());
  38. }
  39. }
  40. }

Set

Set是元素无序并且不可以重复的集合,称为集,Set是接口

HashSet

  • HashSet是Set的一个重要实现类,称为哈希集
  • HashSet的元素无序并且不可重复
  • HashSet中只允许一个null元素
  • 具有良好的存取和查找功能
  • HashSet是在HashMap的基础上实现的

Iterator(迭代器)

  • Iterator接口可以以统一的方式对各种几何元素进行遍历
  • hasNext()方法检测集合中是否还有下一个元素
  • next()方法返回集合中的下一个元素

哈希表

想象一下,有一个数组,其中有100个整数。要查找其中一个元素的话,需要全部遍历一遍,这个效率是很低的。
哈希表可以解决这个问题。

具体做法:

  • 在内存中开辟三个区域来存放正整数,什么数据放到哪个区域,是需要规则的,而这个规则就是HashCode

具体的HashCode如何得到,需要严格的算法,而对于简单需求,Eclipse中自动生成的HashCode就够用了

  • 比如设置HashCode = n % 3,也就是说1放到第二个区域,2放到第三个区域,0放到第一个区域,依次类推
  • 要查找一个整数,先判断在哪个区域,然后再在这个区域里查找,效率就会提高很多了

判断在哪个区域用的就是hashCode()方法,在这个区域里查找用的就是equals()方法

image.png

在HashSet中操作字符串

  1. package com.song.test;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. import java.util.Set;
  5. public class NoticeTest {
  6. public static void main(String[] args) {
  7. Set set = new HashSet();
  8. // 向集合中添加元素
  9. set.add("blue");
  10. set.add("red");
  11. set.add("black");
  12. set.add("yellow");
  13. set.add("white");
  14. // 显示元素
  15. Iterator it = set.iterator();
  16. while (it.hasNext()) {
  17. System.out.print(it.next() + " ");
  18. }
  19. System.out.println();
  20. // 在集合中插入重复元素
  21. // 结果:不会报错,但是也不会出错
  22. set.add("red");
  23. it = set.iterator();
  24. while (it.hasNext()) {
  25. System.out.print(it.next() + " ");
  26. }
  27. }
  28. }

在HashSet中操作自定义对象

Cat.java

  1. package com.set;
  2. public class Cat {
  3. private String name;
  4. private int month;
  5. private String species;
  6. // 构造方法
  7. public Cat(String name, int month, String species) {
  8. super();
  9. this.name = name;
  10. this.month = month;
  11. this.species = species;
  12. }
  13. // getter与setter方法...省略...
  14. // 方便显示输出自定义对象的内容
  15. @Override
  16. public String toString() {
  17. return "[姓名:" + name + ", 年龄:" + month + ", 品种:" + species + "]";
  18. }
  19. // 添加自定义对象需要重写hashCode()方法和equals()方法
  20. @Override
  21. public int hashCode() {
  22. final int prime = 31;
  23. int result = 1;
  24. result = prime * result + month;
  25. result = prime * result + ((name == null) ? 0 : name.hashCode());
  26. result = prime * result + ((species == null) ? 0 : species.hashCode());
  27. return result;
  28. }
  29. @Override
  30. public boolean equals(Object obj) {
  31. // 判断对象是否相等,相等则返回true,不用继续比较属性了
  32. if (this == obj) {
  33. return true;
  34. }
  35. // 判断比较对象obj是否是Cat类对象
  36. if (obj.getClass() == Cat.class) {
  37. // 保存并强制类型装换比较对象
  38. Cat cat = (Cat) obj;
  39. // 只有比较对象和当前对象的所有属性都一致,才认为是相同的
  40. // 所以需要比较name,month,species
  41. return cat.getName().equals(name) && (cat.getMonth() == month) && cat.getSpecies().equals(species);
  42. }
  43. return false;
  44. }
  45. }

CatTest.java - 1
#添加,查找宠物猫信息

  1. package com.set;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. import java.util.Set;
  5. public class CatTest {
  6. public static void main(String[] args) {
  7. // 定义宠物猫对象
  8. Cat huahua = new Cat("花花", 12, "英国短毛猫");
  9. Cat fanfan = new Cat("凡凡", 3, "中华田园猫");
  10. // 将宠物猫对象放入HashSet中
  11. Set set = new HashSet();
  12. set.add(huahua);
  13. set.add(fanfan);
  14. // 显示宠物猫信息
  15. Iterator it = set.iterator();
  16. while (it.hasNext()) {
  17. System.out.println(it.next()); // 自动调用toString()方法
  18. }
  19. System.out.println();
  20. // 再添加一个与花花属性一样的猫
  21. Cat huahua01 = new Cat("花花", 12, "英国短毛猫");
  22. set.add(huahua01);
  23. System.out.println("********* 添加重复数据后的宠物猫信息: **********");
  24. it = set.iterator();
  25. while (it.hasNext()) {
  26. System.out.println(it.next()); // 自动调用toString()方法
  27. }
  28. System.out.println();
  29. // 重新插入一个新宠物猫
  30. Cat huahua02 = new Cat("花花二代", 2, "英国短毛猫");
  31. set.add(huahua02);
  32. System.out.println("********* 添加花花二代后的宠物猫信息: **********");
  33. it = set.iterator();
  34. while (it.hasNext()) {
  35. System.out.println(it.next()); // 自动调用toString()方法
  36. }
  37. System.out.println();
  38. // 在集合中查找花花的信息并输出
  39. System.out.println("********* 查找花花的宠物猫信息: **********");
  40. if (set.contains(huahua)) {
  41. System.out.println("花花找到了");
  42. System.out.println(huahua);
  43. } else {
  44. System.out.println("花花没找到!");
  45. }
  46. System.out.println();
  47. // 在集合中使用名字查找花花的信息
  48. System.out.println("********* 查找名字查找花花的信息: **********");
  49. boolean flag = false;
  50. Cat c = null;
  51. it = set.iterator();
  52. while (it.hasNext()) {
  53. // next()方法返回的值是object类型的,所以需要强制类型转换
  54. // 但是这里你必须知道next()方法取出的对象类型是Cat类型
  55. // 否则,如果转换成其他类型的话,编译不会出错,但是运行的时候就会出错
  56. // 所以存在安全隐患,最好是编译的时候就提示我们出错
  57. // 解决方案请参照CatTest.java -1,使用泛型
  58. c = (Cat) it.next();
  59. if (c.getName().equals("花花")) {
  60. flag = true;
  61. break;
  62. }
  63. }
  64. if (flag) {
  65. System.out.println("花花找到了");
  66. System.out.println(c);
  67. } else {
  68. System.out.println("花花没找到");
  69. }
  70. }
  71. }

[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]

* 添加重复数据后的宠物猫信息: **
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]

* 添加花花二代后的宠物猫信息: **
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]
[姓名:花花二代, 年龄:2, 品种:英国短毛猫]

* 查找花花的宠物猫信息: **
花花找到了
[姓名:花花, 年龄:12, 品种:英国短毛猫]

* 查找名字查找花花的信息: **
花花找到了
[姓名:花花, 年龄:12, 品种:英国短毛猫]

CatTest.java -2
#删除宠溺猫信息

  1. package com.set;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. import java.util.Set;
  5. public class CatTest {
  6. public static void main(String[] args) {
  7. // 定义宠物猫对象
  8. Cat huahua = new Cat("花花", 12, "英国短毛猫");
  9. Cat fanfan = new Cat("凡凡", 3, "中华田园猫");
  10. // 将宠物猫对象放入HashSet中
  11. // <Cat>的意思是:往集合中加入的对象类型,必须是Cat类的对象,其他都不允许加入
  12. Set<Cat> set = new HashSet<Cat>();
  13. set.add(huahua);
  14. set.add(fanfan);
  15. // 显示宠物猫信息
  16. // 同理,这里<Cat>的意思是迭代器中的元素都是Cat类的对象
  17. Iterator<Cat> it = set.iterator();
  18. while (it.hasNext()) {
  19. System.out.println(it.next()); // 自动调用toString()方法
  20. }
  21. System.out.println();
  22. // 再添加一个与花花属性一样的猫
  23. Cat huahua01 = new Cat("花花", 12, "英国短毛猫");
  24. set.add(huahua01);
  25. System.out.println("********* 添加重复数据后的宠物猫信息: **********");
  26. it = set.iterator();
  27. while (it.hasNext()) {
  28. System.out.println(it.next()); // 自动调用toString()方法
  29. }
  30. System.out.println();
  31. // 重新插入一个新宠物猫
  32. Cat huahua02 = new Cat("花花二代", 2, "英国短毛猫");
  33. set.add(huahua02);
  34. System.out.println("********* 添加花花二代后的宠物猫信息: **********");
  35. it = set.iterator();
  36. while (it.hasNext()) {
  37. System.out.println(it.next()); // 自动调用toString()方法
  38. }
  39. System.out.println();
  40. // 在集合中查找花花的信息并输出
  41. System.out.println("********* 查找花花的宠物猫信息: **********");
  42. if (set.contains(huahua)) {
  43. System.out.println("花花找到了");
  44. System.out.println(huahua);
  45. } else {
  46. System.out.println("花花没找到!");
  47. }
  48. System.out.println();
  49. // 在集合中使用名字查找花花的信息
  50. System.out.println("********* 查找名字查找花花的信息: **********");
  51. boolean flag = false;
  52. Cat c = null;
  53. it = set.iterator();
  54. while (it.hasNext()) {
  55. // 由于引入泛型约束,这里不需要强制类型转换,可以直接赋值
  56. c = it.next();
  57. if (c.getName().equals("花花")) {
  58. flag = true;
  59. break;
  60. }
  61. }
  62. if (flag) {
  63. System.out.println("花花找到了");
  64. System.out.println(c);
  65. } else {
  66. System.out.println("花花没找到");
  67. }
  68. System.out.println();
  69. // 删除花花二代的信息并重新输出
  70. // 这里用到增强型for循环,意思是set中的元素依次放到cat对象中
  71. System.out.println("********* 删除花花二代的信息: **********");
  72. for (Cat cat : set) {
  73. if (cat.getName().equals("花花二代")) {
  74. set.remove(cat);
  75. }
  76. }
  77. for (Cat cat : set) {
  78. System.out.println(cat);
  79. }
  80. System.out.println();
  81. // 删除集合中所有的宠物猫信息
  82. System.out.println("********* 删除所有的宠物猫信息: **********");
  83. boolean isClear = set.removeAll(set);
  84. if(isClear) { // set.isEmpty()也是可以的
  85. System.out.println("猫都不见了。。。");
  86. }else {
  87. System.out.println("猫还在");
  88. }
  89. }
  90. }

[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]

* 添加重复数据后的宠物猫信息: **
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]

* 添加花花二代后的宠物猫信息: **
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]
[姓名:花花二代, 年龄:2, 品种:英国短毛猫]

* 查找花花的宠物猫信息: **
花花找到了
[姓名:花花, 年龄:12, 品种:英国短毛猫]

* 查找名字查找花花的信息: **
花花找到了
[姓名:花花, 年龄:12, 品种:英国短毛猫]

* 删除花花二代的信息: **
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]

* 删除所有的宠物猫信息: **
猫都不见了。。。

CatTest.java -3
#删除宠物猫信息过程中可能碰到的问题

  1. package com.set;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. import java.util.Set;
  5. public class CatTest {
  6. public static void main(String[] args) {
  7. // 定义宠物猫对象
  8. Cat huahua = new Cat("花花", 12, "英国短毛猫");
  9. Cat fanfan = new Cat("凡凡", 3, "中华田园猫");
  10. // 将宠物猫对象放入HashSet中
  11. // <Cat>的意思是:往集合中加入的对象类型,必须是Cat类的对象,其他都不允许加入
  12. Set<Cat> set = new HashSet<Cat>();
  13. set.add(huahua);
  14. set.add(fanfan);
  15. // 显示宠物猫信息
  16. // 同理,这里<Cat>的意思是迭代器中的元素都是Cat类的对象
  17. Iterator<Cat> it = set.iterator();
  18. while (it.hasNext()) {
  19. System.out.println(it.next()); // 自动调用toString()方法
  20. }
  21. System.out.println();
  22. // 重新插入一个新宠物猫
  23. Cat huahua02 = new Cat("花花二代", 2, "英国短毛猫");
  24. set.add(huahua02);
  25. System.out.println("********* 添加花花二代后的宠物猫信息: **********");
  26. it = set.iterator();
  27. while (it.hasNext()) {
  28. System.out.println(it.next()); // 自动调用toString()方法
  29. }
  30. System.out.println();
  31. // 删除花花的信息并重新输出
  32. // 这里删除花花的信息时会出错的
  33. // Java为了保持数据的一致性,在查找数据的过程中是不允许删除数据的
  34. // 这里找到花花的时候,查找过程还在继续,所以就出错了
  35. // System.out.println("********* 删除花花的信息: **********");
  36. // for (Cat cat : set) {
  37. // if (cat.getName().equals("花花")) {
  38. // set.remove(cat);
  39. // }
  40. // }
  41. // for (Cat cat : set) {
  42. // System.out.println(cat);
  43. // }
  44. // System.out.println();
  45. // 解决方案1:找到花花之后直接break,不再继续查找
  46. // 适合只删除一个对象的情况
  47. // System.out.println("********* 删除花花的信息: **********");
  48. // for (Cat cat : set) {
  49. // if (cat.getName().equals("花花")) {
  50. // set.remove(cat);
  51. // break;
  52. // }
  53. // }
  54. // for (Cat cat : set) {
  55. // System.out.println(cat);
  56. // }
  57. // System.out.println();
  58. // 解决方案2:使用removeAll()方法
  59. // 适合删除多个对象的情况
  60. System.out.println("********* 删除月龄小于5的宠物猫信息: **********");
  61. Set<Cat> set1 = new HashSet<Cat>();
  62. for (Cat cat : set) {
  63. if (cat.getMonth() < 5) {
  64. set1.add(cat);
  65. }
  66. }
  67. set.removeAll(set1);
  68. for (Cat cat : set) {
  69. System.out.println(cat);
  70. }
  71. System.out.println();
  72. }
  73. }

[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]

* 添加花花二代后的宠物猫信息: **
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]
[姓名:花花二代, 年龄:2, 品种:英国短毛猫]

* 删除月龄小于5的宠物猫信息: **
[姓名:花花, 年龄:12, 品种:英国短毛猫]

Map

  • Map中的数据是以键值对(key-value)的形式存储的
  • key-value以Entry类型的对象实例存在
  • 可以公共key值快速的查找value
  • 一个映射不能包含重复的键
  • 每个键最多只能映射到一个值
  • Map是一个接口

HashMap

  • 基于哈希表的Map接口的实现
  • 允许使用null值和null键
  • key值不允许重复
  • HashMap中的Entry对象是无序排列的

案例1:字典管理

  1. package com.set;
  2. import java.util.HashMap;
  3. import java.util.Iterator;
  4. import java.util.Map;
  5. import java.util.Map.Entry;
  6. import java.util.Scanner;
  7. import java.util.Set;
  8. public class DictionaryDemo {
  9. public static void main(String[] args) {
  10. Map<String, String> animal = new HashMap<String, String>();
  11. System.out.println("请输入三组单词对应的注释,并存放到HashMap中");
  12. Scanner console = new Scanner(System.in);
  13. // 添加数据
  14. int i = 0;
  15. while (i < 3) {
  16. System.out.println("请输入key值(单词):");
  17. String key = console.next();
  18. System.out.println("请输入value值(注释):");
  19. String value = console.next();
  20. animal.put(key, value);
  21. i++;
  22. }
  23. System.out.println();
  24. System.out.println("***********************************");
  25. // 打印输出value的值(直接使用迭代器)
  26. System.out.println("使用迭代器输出所有的value:");
  27. Iterator<String> it = animal.values().iterator();
  28. while (it.hasNext()) {
  29. System.out.print(it.next() + " ");
  30. }
  31. System.out.println();
  32. System.out.println("***********************************");
  33. // 打印输出key 和 value 的值
  34. // 通过entrySet方法
  35. System.out.println("通过entrySet方法得到key - value");
  36. // entrySet是一个集合(Set),其中的每一个元素是Entry,Entry是有键值<String,String>对构成的
  37. Set<Entry<String, String>> entrySet = animal.entrySet();
  38. for (Entry<String, String> entry : entrySet) {
  39. System.out.print(entry.getKey() + "-");
  40. System.out.println(entry.getValue());
  41. }
  42. System.out.println();
  43. System.out.println("***********************************");
  44. // 通过单词找到注释并输出
  45. // 使用keySet方法
  46. System.out.println("请输入要查找的单词:");
  47. String strSearch = console.next();
  48. // 1,取得keyset
  49. Set<String> keySet = animal.keySet();
  50. // 2,遍历keyset
  51. for (String key : keySet) {
  52. if (key.equals(strSearch)) {
  53. System.out.println("找到了!" + "键值对为:" + key + "-" + animal.get(key));
  54. break;
  55. }
  56. }
  57. }
  58. }

案例2:商品管理
#输入异常处理,重复key处理

  1. package com.set;
  2. import java.util.HashMap;
  3. import java.util.Iterator;
  4. import java.util.Map;
  5. import java.util.Scanner;
  6. public class GoodsTest {
  7. public static void main(String[] args) {
  8. Scanner console = new Scanner(System.in);
  9. // 定义HashMap对象
  10. Map<String, Goods> goodsMap = new HashMap<String, Goods>();
  11. int i = 0;
  12. while (i < 3) {
  13. System.out.println("请输入第" + (i + 1) + "条商品信息");
  14. System.out.println("商品编号:");
  15. String goodsId = console.next();
  16. // 判断商品编号是否已存在
  17. if (goodsMap.containsKey(goodsId)) {
  18. System.out.println("该商品编号已经存在!请重新输入!");
  19. continue;
  20. }
  21. System.out.println("商品名称:");
  22. String goodsName = console.next();
  23. System.out.println("商品价格:");
  24. double goodsPrice = 0;
  25. try {
  26. goodsPrice = console.nextDouble();
  27. } catch (Exception e) {
  28. System.out.println("商品价格的格式不正确,请输入数值型数据");
  29. console.next();
  30. continue;
  31. }
  32. // 将商品信息添加到HashMap中
  33. Goods goods = new Goods(goodsId, goodsName, goodsPrice);
  34. goodsMap.put(goodsId, goods);
  35. i++;
  36. }
  37. // 遍历Map,输出商品信息
  38. System.out.println("商品的全部信息为:");
  39. Iterator<Goods> itGoods = goodsMap.values().iterator();
  40. while (itGoods.hasNext()) {
  41. System.out.println(itGoods.next());
  42. }
  43. }
  44. }

排序

对基本数据类型进行排序

  1. package com.sort;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. public class IntSort {
  6. public static void main(String[] args) {
  7. // 对存储在List中的整型数据进行排序
  8. // List中添加的都是对象,所以泛型只能写类的名字
  9. // 由于Java中有包装器类的关系,在list中添加的时候会直接把整型封装成对象
  10. List<Integer> list = new ArrayList<Integer>();
  11. list.add(5);
  12. list.add(9);
  13. list.add(3);
  14. list.add(1);
  15. System.out.println("排序前");
  16. for (int n : list) {
  17. System.out.print(n + " ");
  18. }
  19. System.out.println();
  20. // 对List中的数据进行排序
  21. Collections.sort(list);
  22. System.out.println("排序后");
  23. for (int n : list) {
  24. System.out.print(n + " ");
  25. }
  26. System.out.println();
  27. }
  28. }

排序前
5 9 3 1
排序后
1 3 5 9

对字符串类型进行排序

  1. package com.sort;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. public class StringSort {
  6. public static void main(String[] args) {
  7. // 对存放在List中的字符串进行排序
  8. List<String> list = new ArrayList<String>();
  9. list.add("orange");
  10. list.add("blue");
  11. list.add("yellow");
  12. list.add("gray");
  13. System.out.println("排序前");
  14. for (String n : list) {
  15. System.out.print(n + " ");
  16. }
  17. System.out.println();
  18. // 对List中的数据进行排序
  19. Collections.sort(list);
  20. System.out.println("排序后");
  21. for (String n : list) {
  22. System.out.print(n + " ");
  23. }
  24. System.out.println();
  25. }
  26. }

排序前
orange blue yellow gray
排序后
blue gray orange yellow

Comparator接口

  • 强行对某个对象进行整体排序的比较函数
  • 可以将Comparator传递给sort方法(如Collecddtions.sort或Arrays.sort)
  • int compare(T o1, T o2) 比较用来排序的两个参数

前提o1>o2,想要升序排序,就返回正整数
前提o1>o2,想要降序排序,就返回负整数

Cat.java

  1. package com.sort;
  2. public class Cat {
  3. private String name;
  4. private int month;
  5. private String species;
  6. // 构造方法
  7. public Cat(String name, int month, String species) {
  8. super();
  9. this.name = name;
  10. this.month = month;
  11. this.species = species;
  12. }
  13. // getter与setter方法
  14. ...
  15. // 方便显示输出自定义对象的内容
  16. @Override
  17. public String toString() {
  18. return "[名字:" + name + ", 年龄:" + month + ", 品种:" + species + "]";
  19. }
  20. }

NameComparator.java

  1. package com.sort;
  2. import java.util.Comparator;
  3. public class NameComparator implements Comparator<Cat> {
  4. @Override
  5. public int compare(Cat o1, Cat o2) {
  6. // 按名字升序排序
  7. String name1 = o1.getName();
  8. String name2 = o2.getName();
  9. // return name2.compareTo(name1); // 降序
  10. return name1.compareTo(name2); // 升序
  11. }
  12. }

AgeComparator

  1. package com.sort;
  2. import java.util.Comparator;
  3. public class AgeComparator implements Comparator<Cat> {
  4. @Override
  5. public int compare(Cat o1, Cat o2) {
  6. // 按年龄降序排序
  7. int age1 = o1.getMonth();
  8. int age2 = o2.getMonth();
  9. return age2 - age1;
  10. }
  11. }

CatTest.java

  1. package com.sort;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. public class CatTest {
  6. public static void main(String[] args) {
  7. // 按名字升序排序
  8. Cat huahua = new Cat("huahua", 4, "英国短毛猫");
  9. Cat fanfan = new Cat("fanfan", 2, "中华田园猫");
  10. Cat maomao = new Cat("maomao", 3, "中华田园猫");
  11. List<Cat> catList = new ArrayList<Cat>();
  12. catList.add(huahua);
  13. catList.add(fanfan);
  14. catList.add(maomao);
  15. // 排序前
  16. System.out.println("排序前:");
  17. for (Cat cat : catList) {
  18. System.out.println(cat);
  19. }
  20. // 按名字进行升序排序
  21. Collections.sort(catList, new NameComparator());
  22. System.out.println("按名字排序后:");
  23. for (Cat cat : catList) {
  24. System.out.println(cat);
  25. }
  26. // 按年龄进行降序排序
  27. Collections.sort(catList, new AgeComparator());
  28. System.out.println("按年龄降序后:");
  29. for (Cat cat : catList) {
  30. System.out.println(cat);
  31. }
  32. }
  33. }

排序前:
[名字:huahua, 年龄:4, 品种:英国短毛猫]
[名字:fanfan, 年龄:2, 品种:中华田园猫]
[名字:maomao, 年龄:3, 品种:中华田园猫]

按名字排序后:
[名字:fanfan, 年龄:2, 品种:中华田园猫]
[名字:huahua, 年龄:4, 品种:英国短毛猫]
[名字:maomao, 年龄:3, 品种:中华田园猫]

按年龄降序后:
[名字:huahua, 年龄:4, 品种:英国短毛猫]
[名字:maomao, 年龄:3, 品种:中华田园猫]
[名字:fanfan, 年龄:2, 品种:中华田园猫]

Comparable接口

  • 此接口强行对实现它的每个类的对象进行整体排序
  • 这种排序被成为类的自然排序,类的 compareTo 方法被成为它的自然比较方法
  • 对于集合,通过调用Collections.sort方法进行排序
  • 对于数组,通过调用Array.sort()方法进行排序
  • int compareTo(T o)方法

该对象小于,等于或大于指定对象,则分别返回负整数,零或正整数

Goods.java

  1. package com.sort;
  2. public class Goods implements Comparable<Goods> {
  3. private String id;
  4. private String name;
  5. private double price;
  6. // 构造方法
  7. public Goods(String id, String name, double price) {
  8. super();
  9. this.id = id;
  10. this.name = name;
  11. this.price = price;
  12. }
  13. // getter和setter
  14. ...
  15. public String toString() {
  16. return "商品编号:" + id + ",商品名称:" + name + ",商品价格:" + price;
  17. }
  18. @Override
  19. public int compareTo(Goods o) {
  20. // 取出商品价格
  21. double price1 = this.getPrice();
  22. double price2 = o.getPrice();
  23. // 当price1和price2的差小于1时,返回结果为0,可以根据需求做进一步判断
  24. // 这里只是掩饰compareTo,不再追求这种细节
  25. return new Double(price2 - price1).intValue();
  26. }
  27. }

GoodsTest.java

  1. package com.sort;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. public class GoodsTest {
  6. public static void main(String[] args) {
  7. Goods g1 = new Goods("s0001", "手机", 2000);
  8. Goods g2 = new Goods("s0002", "冰箱", 5000);
  9. Goods g3 = new Goods("s0003", "电视机", 3000);
  10. List<Goods> goodsList = new ArrayList<Goods>();
  11. goodsList.add(g1);
  12. goodsList.add(g2);
  13. goodsList.add(g3);
  14. // 排序前
  15. System.out.println("排序前:");
  16. for (Goods goods : goodsList) {
  17. System.out.println(goods);
  18. }
  19. // 排序后
  20. Collections.sort(goodsList);
  21. System.out.println("排序后:");
  22. for (Goods goods : goodsList) {
  23. System.out.println(goods);
  24. }
  25. }
  26. }

排序前:
商品编号:s0001,商品名称:手机,商品价格:2000.0
商品编号:s0002,商品名称:冰箱,商品价格:5000.0
商品编号:s0003,商品名称:电视机,商品价格:3000.0

排序后:
商品编号:s0002,商品名称:冰箱,商品价格:5000.0
商品编号:s0003,商品名称:电视机,商品价格:3000.0
商品编号:s0001,商品名称:手机,商品价格:2000.0

image.png
补充:Comparator可以实现多个比较方法,Comparable只能实现一个比较方法