[关闭]
@xujun94 2016-07-02T16:06:42.000000Z 字数 6114 阅读 2371

java实现对象的排序(List和Map)

List和Map的排序


在实际的开发当中,我们经常 在文件浏览的时候经常有多种浏览方式,按时间整箱排序,逆向排序,按大小正逆向排序 ,按 按价格正逆向排序,这些其实都是List和Map中对象的排序,本篇博客不打算从实现文件浏览界面了,因为这些你随便去网上找一下,源码很多,本篇博客打算从java 的实现入门

关于二分查找的,可以参考我的这篇博客二分查找的相关算法题

关于归并排序的的,可以参考我的这篇博客归并排序 递归版和非递归版的实现(java)

关于快速排序的,可以参考我的这篇博客 快速排序的相关算法题(java)

转载请注明原博客地址: http://blog.csdn.net/gdutxiaoxu/article/details/50535340

本文固定链接: https://www.zybuluo.com/xujun94/note/424545

首先我们先来了解了解一下java帮我们封装好的几种排序

  1. java.util.Collections.sort(java.util.List)
    • 这个要求我们的对象实现java.lang.Comparable接口,并重写compareTo方法
  2. java.util.Collections.sort(java.util.List, java.util.Comparator)
    • 这个要求我们提供Comparator接口的 实例对象,作为比较的基准

那种两种方法有什么不同呢?

1.说白了,实现第一种方法的即对象实现java.lang.Comparable接口可以说是一个内部比较器,以后我们如果要修改排序方式,必须要修改原来的类,这明显违背了java对拓展开饭 ,对修改关闭的原则
2. 实现第二种方法的,相对于第一种方法来说,它可以说是一个外部比较器,修改排序方法,不需要修改原来的代码,相对来说比较灵活

下面我们一起来看一下怎样实现

  1. 实现Comparable接口的

    • 如果你有一个新的类,比如Player,那么你要想对其进行排序,就让其实现Comparable接口,并且实现compareTo方法。比如比想按照年龄的大小来排序,从小的进行,那么你就实现如下:
  1. //Product.java
  2. import java.util.Date;
  3. public class Product implements Comparable {//类内比较
  4. private String name;
  5. private Date date;
  6. private int price;
  7. public int getPrice() {
  8. return price;
  9. }
  10. public void setPrice(int price) {
  11. this.price = price;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public Date getDate() {
  20. return date;
  21. }
  22. public void setDate(Date date) {
  23. this.date = date;
  24. }
  25. //用于类内比较
  26. @Override//覆写compareTo(Object o)方法
  27. public int compareTo(Product o) {
  28. return -this.date.compareTo(o.date);
  29. }
  30. }
  1. List<Product > productList=new ArrayList<Product >();
  2. playerList.add(new Product ())
  3. .......
  4. Collections.sort(productList);

2.实现第二种方法的,即Comparator接口的

  1. public class Product{
  2. private String name;
  3. private Date date;
  4. private int price;
  5. public int getPrice() {
  6. return price;
  7. }
  8. public void setPrice(int price) {
  9. this.price = price;
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public Date getDate() {
  18. return date;
  19. }
  20. public void setDate(Date date) {
  21. this.date = date;
  22. }
  23. }
  1. //ProductComparator.java
  2. import java.util.Date;
  3. import java.util.Comparator;
  4. public class ProductComparator implements Comparator<Product> {
  5. // 对象的排序方式[升、降]
  6. public static boolean sortASC = true;
  7. // 对象的排序属性
  8. public static boolean sortByName = false;
  9. public static boolean sortByDate = false;
  10. public static boolean sortByPrice = false;
  11. @Override
  12. public int compare(Product pro1, Product pro2) {
  13. int result = 0;
  14. if(sortASC){
  15. if(sortByName){
  16. String pro1name = pro1.getName();
  17. String pro2name = pro2.getName();
  18. result = pro1name.compareTo(pro2name);
  19. }else if(sortByDate){
  20. Date pro1Date = pro1.getDate();
  21. Date pro2Date = pro2.getDate();
  22. result = pro1Date.compareTo(pro2Date);
  23. }else if(sortByPrice){
  24. Integer pro1Price = pro1.getPrice();
  25. Integer pro2Price = pro2.getPrice();
  26. result = pro1Price.compareTo(pro2Price);
  27. }
  28. }else{
  29. if(sortByName){
  30. String pro1name = pro1.getName();
  31. String pro2name = pro2.getName();
  32. result = -pro1name.compareTo(pro2name);
  33. }else if(sortByDate){
  34. Date pro1Date = pro1.getDate();
  35. Date pro2Date = pro2.getDate();
  36. result = -pro1Date.compareTo(pro2Date);
  37. }else if(sortByPrice){
  38. Integer pro1Price = pro1.getPrice();
  39. Integer pro2Price = pro2.getPrice();
  40. result = -pro1Price.compareTo(pro2Price);
  41. }
  42. }
  43. return result;
  44. }
  45. }

写到这里,区别基本已经讲解完毕,接下来看一下测试代码

  1. //测试代码
  2. import java.text.ParseException;
  3. import java.text.SimpleDateFormat;
  4. import java.util.ArrayList;
  5. import java.util.Collections;
  6. import java.util.Iterator;
  7. import java.util.List;
  8. import java.util.Locale;
  9. public class ProductSort {
  10. public static void main(String[] args) throws ParseException {
  11. Product pro1 = new Product();
  12. pro1.setName("pro1");
  13. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-dd-MM",Locale.CHINA);
  14. pro1.setDate(sdf.parse("2009-03-23"));
  15. pro1.setPrice(89);
  16. Product pro2 = new Product();
  17. pro2.setName("proc2");
  18. pro2.setDate(sdf.parse("2009-02-23"));
  19. pro2.setPrice(45);
  20. Product pro3 = new Product();
  21. pro3.setName("proc3");
  22. pro3.setDate(sdf.parse("2009-01-23"));
  23. pro3.setPrice(83);
  24. Product pro4 = new Product();
  25. pro4.setName("proc4");
  26. pro4.setDate(sdf.parse("2009-01-23"));
  27. pro4.setPrice(800);
  28. List<Product> productList = new ArrayList<Product>();
  29. productList.add(pro1);
  30. productList.add(pro3);
  31. productList.add(pro2);
  32. productList.add(pro4);
  33. System.out.println("排序前————————————————————");
  34. for(Product p: productList){
  35. System.out.println(p.getName()+"----"+p.getPrice()+"----"+p.getDate());
  36. }
  37. ProductComparable sort = new ProductComparable();
  38. ProductComparable.sortASC = false;//降序
  39. ProductComparable.sortByPrice=true; //设置排序属性生效
  40. Collections.sort(productList,sort);
  41. System.out.println("排序后————————————————————");
  42. for(Iterator<Product> iter = productList.iterator(); iter.hasNext();){
  43. Product p = (Product)iter.next();
  44. System.out.println(p.getName()+"----"+p.getPrice()+"---"+p.getDate());
  45. }
  46. }
  47. }

总结,推荐使用Comparator实现排序

因为 你用一个第三方的类,但他没实现Comparable接口,而你又不能改他代码;另外,类一旦写好后是不允许修改的,但可以扩展,所以只能用Comparator接口


下面讲解怎样实现Map排序

Map是键值对,所以既可以按照键进行排序,也可以按照值进行排序。通常因为键不能同,但是值可以同,所以很多都是用值来进行排序。

### 原理解析

  1. Map遍历的时候要使用一个东西叫做Map.Entry,假如你有一个Map的对象map,那么你可以使用map.entrySet()获取一个set对象,里面装的都是Map.Entry,如果你想遍历,很简单地使用iterator就可以获取里面的所有元素。
  2. 如果你要排序,那么就最好是将这个set装到一个list里面去,然后定义一个Comparator对象,在里面实现compare方法,返回一个差值,比如运动员得分的差值,
  3. 然后使用Collections.sort方法,将list对象和comparator对象传进去,排序就完成了。

下面看一下例子

  1. public class MapSort{
  2. public static void main(String[] args){
  3. Map<String, Player> map = new HashMap<String, Player>();
  4. Player p1 = new Player("John", 1000);
  5. Player p2 = new Player("Ben", 3000);
  6. Player p3 = new Player("Jack", 2000);
  7. map.put(p1);
  8. map.put(p2);
  9. map.put(p3);
  10. //将Map里面的所以元素取出来先变成一个set,然后将这个set装到一个list里面
  11. List<Map.Entry<String, Player>> list = new ArrayList<Map.Entry<String, Player>>(map.entrySet());
  12. //定义一个comparator
  13. Comparator<Map.Entry<String, Player>> comparator = new Comparator<Map.Entry<String, Player>>(){
  14. @Override
  15. public int compare(Entry<String, Player> p1, Entry<String, Player> p2){
  16. //之所以使用减号,是想要按照分数从高到低来排列
  17. return -(p1.getValue().score - p2.getValue().score);
  18. }
  19. };
  20. Collections.sort(list, comparator);
  21. for(Map.Entry<String, Player> entry:list){
  22. System.out.println(entry.getValue().name + ":" + entry.getValue().score);
  23. }
  24. }
  25. }
  26. class Player{
  27. String name;
  28. int score;
  29. public Player(String name, int score){
  30. this.name == name;
  31. this.score == score;
  32. }
  33. }

这样排序下来,最后就会输出如下内容
Ben:3000
Jack:2000
John:1000

好了,今天的List,Map排序讲解到此为止,对排序的实现方式还不理解的,建议重新去看一下 八大排序和二分查找,因为这里面的思想很重要

关于二分查找的,可以参考我的这篇博客二分查找的相关算法题

关于归并排序的的,可以参考我的这篇博客归并排序 递归版和非递归版的实现(java)

关于快速排序的,可以参考我的这篇博客 快速排序的相关算法题(java)

转载请注明原博客地址: http://blog.csdn.net/gdutxiaoxu/article/details/50535340

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注