浅谈java Collection中的排序问题_java

这里讨论list、set、map的排序,包括按照map的value进行排序。

1)list排序

list排序可以直接采用Collections的sort方法,也可以使用Arrays的sort方法,归根结底Collections就是调用Arrays的sort方法。

public static <T> void sort(List<T> list, Comparator<? super T> c) {
  Object[] a = list.toArray();
  Arrays.sort(a, (Comparator)c);
  ListIterator i = list.listIterator();
  for (int j=0; j<a.length; j++) {
    i.next();
    i.set(a[j]);
  }
  }

如果是自定义对象,需要实现Comparable接口使得对象自身就有“比较”的功能,当然我们也可以在外部使用Comparator来规定其排序。

例如:

package com.fox; 

/**
 * @author huangfox
 * @desc
 */
public class User implements Comparable<User> { 

  private String name;
  private int age; 

  public User() {
  } 

  public User(String name, int age) {
    super();
    this.name = name;
    this.age = age;
  } 

  @Override
  public String toString() {
    return "name:" + name + ",age:" + age;
  } 

  public String getName() {
    return name;
  } 

  public void setName(String name) {
    this.name = name;
  } 

  public int getAge() {
    return age;
  } 

  public void setAge(int age) {
    this.age = age;
  } 

  @Override
  public int compareTo(User o) {
    if (o.age < this.age)
      return 1;
    else if (o.age > this.age)
      return -1;
    else
      return 0;
  } 

  /**
   * @param args
   */
  public static void main(String[] args) {
    User u1 = new User("fox", 11);
    User u2 = new User("fox2", 21);
    System.out.println(u2.compareTo(u1));
  } 

}

排序:

// List<User> us = new ArrayList<User>();
    List<User> us = new LinkedList<User>();
    us.add(new User("f5", 12));
    us.add(new User("f2", 22));
    us.add(new User("f3", 2));
    us.add(new User("f4", 14));
    us.add(new User("f5", 32));
    us.add(new User("f4", 12));
    us.add(new User("f7", 17));
    us.add(new User("f8", 52));
    System.out.println(us.toString());
    long bt = System.nanoTime();
    Collections.sort(us, new Comparator<User>() { 

      @Override
      public int compare(User o1, User o2) {
        if (o1.getAge() < o2.getAge())
          return -1;
        else if (o1.getAge() > o2.getAge())
          return 1;
        else
          return o1.getName().compareTo(o2.getName());
      }
    });
    long et = System.nanoTime();
    System.out.println(et - bt);
    System.out.println(us.toString());

当然这里可以直接Collections.sort(us),这里用Comparator对User自身的比较方法compareTo做了一点点优化(对相同年龄的人根据用户名排序,String的排序)。

简单提一下,Arrays的排序采用的是插入排序和归并排序,当数组长度较小时直接插入排序。

2)set排序

set包括HashSet和TreeSet,HashSet是基于HashMap的,TreeSet是基于TreeMap的。

TreeMap是用红黑树实现,天然就具有排序功能,“天然就具有排序功能”是指它拥有升序、降序的迭代器。

那么HashSet怎么排序呢?我们可以将HashSet转成List,然后用List进行排序。

例如:

Set<User> us = new HashSet<User>();
    // Set<User> us = new TreeSet<User>();
    // Set<User> us = new TreeSet<User>(new Comparator<User>() {
    //
    // @Override
    // public int compare(User o1, User o2) {
    // if (o1.getAge() < o2.getAge())
    // return -1;
    // else if (o1.getAge() > o2.getAge())
    // return 1;
    // else
    // return o1.getName().compareTo(o2.getName());
    // }
    // });
    us.add(new User("f5", 12));
    us.add(new User("f2", 22));
    us.add(new User("f3", 2));
    us.add(new User("f4", 14));
    us.add(new User("f5", 32));
    us.add(new User("f4", 12));
    us.add(new User("f7", 17));
    us.add(new User("f8", 52));
    // set -> array
    List<User> list = new ArrayList<User>(us);
    System.out.println(list);
    Collections.sort(list);
    System.out.println(list);

也可以将HashSet转换成数组用Arrays排序。

3)map排序

map包括HashMap和TreeMap,上面已经提过,TreeMap用红黑树实现,天然具有排序功能。

那么HashMap怎么按“key”排序呢?方法很简单,用HashMap来构造一个TreeMap。

Map<String, Integer> us = new HashMap<String, Integer>();
    // Map<String, Integer> us = new TreeMap<String, Integer>();
    us.put("f1", 12);
    us.put("f2", 13);
    us.put("f5", 22);
    us.put("f4", 42);
    us.put("f3", 15);
    us.put("f8", 21);
    us.put("f6", 123);
    us.put("f7", 1);
    us.put("f9", 19);
    System.out.println(us.toString());
    System.out.println(new TreeMap<String, Integer>(us));

怎么按照“value”进行排序?

// 按照value排序
    Set<Entry<String, Integer>> ks = us.entrySet();
    List<Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(
        ks);
    Collections.sort(list, new Comparator<Entry<String, Integer>>() { 

      @Override
      public int compare(Entry<String, Integer> o1,
          Entry<String, Integer> o2) {
        if (o1.getValue() < o2.getValue())
          return -1;
        else if (o1.getValue() > o2.getValue())
          return 1;
        return 0;
      }
    });
    System.out.println(list);

将map的Entry提出成set结构,然后将set转成list,最后按照list进行排序。

以上这篇浅谈java Collection中的排序问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 排序
collection
java collection 排序、collection排序、collection sort排序、collectionutils 排序、collectionview 排序,以便于您获取更多的相关知识。

时间: 2024-11-03 00:42:18

浅谈java Collection中的排序问题_java的相关文章

浅谈java线程中生产者与消费者的问题_java

一.概念 生产者与消费者问题是一个金典的多线程协作的问题.生产者负责生产产品,并将产品存放到仓库:消费者从仓库中获取产品并消费.当仓库满时,生产者必须停止生产,直到仓库有位置存放产品:当仓库空时,消费者必须停止消费,直到仓库中有产品. 解决生产者/消费者问题主要用到如下几个技术:1.用线程模拟生产者,在run方法中不断地往仓库中存放产品.2.用线程模拟消费者,在run方法中不断地从仓库中获取产品.3  . 仓库类保存产品,当产品数量为0时,调用wait方法,使得当前消费者线程进入等待状态,当有新

浅谈Java程序设计中继承的利与弊

摘要:在 Java 中,正确应用继承,能够达到代码重用.增强可靠性.简化程序设计.提高编程效率.并使之易于维护的目的.但是一个程序中过多地使用继承是不可取的,它会带来一些局限性.本文就继承的利与弊进行一个分析. 关键词:继承;超类;子类;代码重用 继承在 Java 面向对象编程中是与生俱来的.所有类,无论是API,还是编程人员自己编写的,都自动继承于 Java 所有类的始祖--Object 类,代表了所有类的共性. 一.继承的概述 继承是面向对象设计的特点之一.和现实世界中的继承概念一样,继承就

浅谈Java编程中的单例设计模式_java

写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像findbugs等代码检查工具还会认为使用System.out.println()是一个bug. 为什么作为Java新手神器的System.out.println(),到了真正项目开发当中会被唾弃呢?其实只要细细分析,你就会发现它的很多弊端.比如不可控制,所有的日志都会在项目上线后照常打印,从而降低运

浅谈Java编程中的内存泄露情况_java

必须先要了解的 1.c/c++是程序员自己管理内存,Java内存是由GC自动回收的. 我虽然不是很熟悉C++,不过这个应该没有犯常识性错误吧. 2.什么是内存泄露? 内存泄露是指系统中存在无法回收的内存,有时候会造成内存不足或系统崩溃. 在C/C++中分配了内存不释放的情况就是内存泄露. 3.Java存在内存泄露 我们必须先承认这个,才可以接着讨论.虽然Java存在内存泄露,但是基本上不用很关心它,特别是那些对代码本身就不讲究的就更不要去关心这个了. Java中的内存泄露当然是指:存在无用但是垃

浅谈Java三大框架与应用_java

前言:对于一个程序员来说,尤其是在java web端开发的程序员,三大框架:Struts+Hibernate+Spring是必须要掌握熟透的,因此,下面谈谈java三大框架的基本概念和原理. JAVA三大框架 一.Spring Spring是一个解决了许多在J2EE开发中常见的问题的强大框架. Spring提供了管理业务对象的一致方法并且鼓励了注入对接口编程而不是对类编程的良好习惯.Spring的架构基础是基于使用JavaBean属性的Inversion of Control容器.然而,这仅仅是

浅谈java实现重载的方法_java

重载(重新载选方法): java允许在一个类中,存在多个方法拥有相同的名字,但在名字相同的同时,必须有不同的参数,这就是重载,编译器会根据实际情况挑选出正确的方法,如果编译器找不到匹配的参数或者找出多个可能的匹配就会产生编译时错误,这个过程被称为重载的解析. 重载包括:普通方法的重载和构造方法的重载 方法:即函数(文中我们统称之为"方法"),是一个固定的一个程序段,或称其为一个子程序,它在可以实现固定运算功能.而且,同时还带有一个入口和一个出口,所谓的入口,就是函数所带的各个参数,我们

浅谈Java生命周期管理机制_java

先扯再说 最近一直在研究某个国产开源的MySQL数据库中间件,拉下其最新版的代码到eclipse后,启动起来,然后做各种测试和代码追踪:用完想要关闭它时,拉出它的STOP类想要运行时,发现这个类里赫然只写以下几行代码,于是我感觉瞬间受到了很多伤害. public static void main(String[] args) { System.out.println(new Date() + ",server shutdown!"); } 这个中间件启动和运行的时候,开启了监听,启动着

浅谈Java中常用数据结构的实现类 Collection和Map_java

线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构.这些类均在java.util包中.本文试图通过简单的描述,向读者阐述各个类的作用以及如何正确使用这些类. Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├HashMap └WeakHashMap Collection接口 Collection是最基本的集合接口,一个C

浅谈java 执行jar包中的main方法_java

浅谈java 执行jar包中的main方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar 执行后总是运行指定的主方法,如果 jar 中有多个 main 方法,那么如何运行指定的 main 方法呢? 用下面的命令试试看: java -classpath ****.jar ****.****.className [args] "****.****"表示"包名": "className"表示&