常需要对list进行排序,小到List,大到对自定义的类进行排序。不需要自行归并或堆排序。简单实现一个接口即可。

本文先会介绍利用Collections对List进行排序,继而讲到Collections.sort的原理,

再讲到如何对自定义类进行排序,

最后会介绍利用Collections sort对自定义对象进行排序的另外一种方法,并将两种排序进行了简单的性能比较。

1、对List排序及Collections.sort的原理

代码如下

List stringList = new ArrayList();

stringList.add("nice");

stringList.add("delicious");

stringList.add("able");

stringList.add("moon");

stringList.add("try");

stringList.add("friend");

Collections.sort(stringList);

for (String str : stringList) {

System.out.println(str);

}

其中Collections为java.util.Collections。

查看Collections中的sort实现

@SuppressWarnings("unchecked")

public static > void sort(List list) {

Object[] array = list.toArray();

Arrays.sort(array);

int i = 0;

ListIterator it = list.listIterator();

while (it.hasNext()) {

it.next();

it.set((T) array[i++]);

}

}

从中可以看出排序主体为Arrays.sort(array);Arrays的sort实现为

public static void sort(Object[] array) {

// BEGIN android-changed

ComparableTimSort.sort(array);

// END android-changed

}

继续追踪,ComparableTimSort的sort实现ComparableTimSort.sort

static void sort(Object[] a)到static void sort(Object[] a, int lo, int hi)到private static void binarySort(Object[] a, int lo, int hi, int start)。在binarySort中用于大小比较部分为

Comparable pivot = (Comparable) a[start];

int left = lo;

int right = start;

assert left <= right;

while (left < right) {

int mid = (left + right) >>> 1;

if (pivot.compareTo(a[mid]) < 0)

right = mid;

else

left = mid + 1;

}

会调用Object的compareTo进行比较。而默认类似String和Integer类型都已经覆盖compareTo方法。所以可以自行进行比较

2、对自定义类进行比较

通过上面的介绍了解了Collections排序的原理,下面介绍下自定义对象的排序,先查看下Integer和String的比较原理、然后介绍如何对自定义类进行比较

2.1 我们查看Object的实现发现其中并没有compareTo方法,

再看下Integer定义

public final class Integer extends Number implements Comparable

再看下String的定义

public final class String implements java.io.Serializable, Comparable, CharSequence

我们可以发现他们都继承自Comparable

2.2 查看Comparable接口

可以发现Comparable中只有一个方法

Java代码

public int compareTo(T o);

也就是说实际上binarySort方法中调用的是Comparable的compareTo方法,以此可知只要继承自Comparable,

并实现compareTo即可调用Collections.sort对自定义对象进行排序

2.3 自定义类的比较

下面代码为对User进行排序,首先按姓名字母先后排序,若姓名相同,则按年龄由小到大排序

Java代码

public class MainTest {

public static void main(String[] args) {

List userList = new ArrayList();

userList.add(new User("Lucy", 19));

userList.add(new User("Jack", 19));

userList.add(new User("Jim", 19));

userList.add(new User("James", 19));

userList.add(new User("Herry", 19));

userList.add(new User("Luccy", 19));

userList.add(new User("James", 18));

userList.add(new User("Herry", 20));

Collections.sort(userList);

for (User user : userList) {

System.out.println(user.getName() + "\t\t" + user.getAge());

}

}

private static class User implements Comparable {

private String name;

private int age;

public User(String name, int age){

this.name = name;

this.age = age;

}

@Override

public int compareTo(User another) {

int compareName = this.name.compareTo(another.getName());

if (compareName == 0) {

return (this.age == another.getAge() ? 0 : (this.age > another.getAge() ? 1 : -1));

}

return compareName;

}

public String getName() {

return name;

}

public int getAge() {

return age;

}

}

}

执行后输出为:

Xml代码:

Herry 19

Herry 20

Jack 19

James 18

James 19

Jim 19

Luccy 19

Lucy 19

可以看出只需两点即可

a、继承自Comparable

Java代码

private static class User implements Comparable

b、实现compareTo方法

上面的public int compareTo(User another)为比较的主体

可以看到其中int compareName = this.name.compareTo(another.getName());表示比较姓名

若大于返回1,等于返回0,小于会返回-1。

若相等则按照int age的大小进行比较。

上面的大于返回1,等于返回0,小于会返回-1也是用来binarySort比较的依据。

3、利用Collectionssort的重载函数对自定义对象进行排序

代码如下,仍同2中的一样先比较姓名,若相等再比较年龄输出

Java代码

public class MainTest {

public static void main(String[] args) {

List userList = new ArrayList();

userList.add(new User("Lucy", 19));

userList.add(new User("Jack", 19));

userList.add(new User("Jim", 19));

userList.add(new User("James", 19));

userList.add(new User("Herry", 19));

userList.add(new User("Luccy", 19));

userList.add(new User("James", 18));

userList.add(new User("Herry", 20));

Collections.sort(userList, new Comparator() {

public int compare(User user1, User user2) {

int compareName = user1.getName().compareTo(user2.getName());

if (compareName == 0) {

return (user1.getAge() == user2.getAge() ? 0 : (user1.getAge() > user2.getAge() ? 1 : -1));

}

return compareName;

}

});

for (User user : userList) {

System.out.println(user.getName() + "\t\t" + user.getAge());

}

}

private static class User {

private String name;

private int age;

public User(String name, int age){

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public int getAge() {

return age;

}

}

}

可以看出其中

Java代码

Collections.sort(userList, new Comparator())

为比较的主体,并且实现了Comparator的compare方法。下面介绍下此种方法的原理

追踪Collections的

Java代码

public static void sort(List list, Comparator super T> c)

Java代码

public static void sort(T[] a, Comparator super T> c)

Java代码

private static void mergeSort(Object[] src, Object[] dest, int low, int high, int off, Comparator c)

可以发现其中代码如下:

Java代码

if (length < INSERTIONSORT_THRESHOLD) {

for (int i=low; i

for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)

swap(dest, j, j-1);

return;

}

调用Comparator的compare方法

4、以上两种排序性能的比较

binarySort需要进行nlg(n)次的比较,最坏情况下n^2次的移动

mergeSort是不断进行二分,二分到很小部分后进行插入排序。所以会比较nlg(n)次,移动nlg(n)次。但它需要先复制一份源数据,所以会多占用一倍的空间

所以实际情况可以根据需要选择

以上这篇浅谈对象数组或list排序及Collections排序原理就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

java list数组排序_浅谈对象数组或list排序及Collections排序原理相关推荐

  1. java bitset用途_浅谈Java BitSet使用场景和代码示例

    搜索热词 @H_502_0@一.什么是BitSet? @H_502_0@ 注:以下内容来自JDK API: @H_502_0@ BitSet类实现了一个按需增长的位向量.位Set的每一个组件都有一个b ...

  2. java缓存同步_浅谈JSON的数据交换、缓存问题和同步问题

    JSON轻量级的数据交换格式 相对于XML来说,JSON的解析速度更快,文档更小. JSON的格式 {属性名:属性值,属性名:属性值,--} 属性名的类型可以是string,number,boolea ...

  3. java 多线程同步_浅谈Java多线程(状态、同步等)

    Java多线程是Java程序员必须掌握的基本的知识点,这块知识点比较复杂,知识点也比较多,今天我们一一来聊下Java多线程,系统的整理下这部分内容. 一.Java中线程创建的三种方式: 1.通过继承T ...

  4. java手动回收_浅谈java是如何做资源回收补救的

    学习java的过程,我们经常谈论一个对象的回收,尤其是资源类型,如果没有显示的关闭,对象就被回收了,说明出现了资源泄漏.java本身为了防止这种情况,做了一些担保的方式,确保可以让未关闭的资源合理回收 ...

  5. java同名函数_浅谈Java 继承接口同名函数问题

    在Java中如果一个类同时继承接口A与B,并且这两个接口中具有同名方法,会怎么样? 动手做实验: interface A{ void fun(); } interface B{ void fun(); ...

  6. java扫码枪键盘_浅谈在react中如何实现扫码枪输入

    触发原理 原理就是监听键盘输入,比如扫一个为6970596130126的69条形码,用扫码枪扫一下会在光标位置依次输出: 6 9 7 0 5 9 6 1 3 0 2 6 但这不是完整的,所以需要写一个 ...

  7. 00005在java结果输出_浅谈Java反序列化漏洞原理(案例未完善后续补充)

    摘要: 0005,这个16进制流基本上也意味者java反序列化的开始:(2)HTTP:必有rO0AB,其实这就是aced0005的base64编码的结果:以上意味着存在Java反序列化,可尝试构造pa ...

  8. java list翻转_浅谈Java数据结构中的常见问题

    1.常用数据结构 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素间的关系组成.常用的数据有:数组.栈.队列.链表.树.图.堆.散列表. 1)数组:在内存中连续存储多个元素的 ...

  9. java反射 用处_浅谈Java反射

    一.何为反射 反射就是对于任何一个类都能知道这个类的的所有属性和方法,并且对于任何一个对象都能调用他的属性和方法,而且能修改其属性. 二.反射的作用 就我的理解来看,通常我们在写代码的时会非常强调代码 ...

最新文章

  1. JWT 身份认证优缺点分析以及常见问题解决方案
  2. Ubuntu16.04 python2.7升级python3.5
  3. Java多线程详解[狂神说Java]
  4. cent 8.0 安装tomcat 9.0_JDK-TOMCAT-MYSQL安装
  5. 怎样提高团队管理能力5
  6. 【solr基础教程之九】客户端
  7. 缓冲运动之框架開始一级简单框架实例
  8. php 动态加载JavaScript文件或者css文件
  9. Python中的实用小技巧,可以省下不是事情,喜欢记得收下
  10. Linux下oracle em安装,关于在linux下手动安装oracle之后,安装em的问题
  11. 一文深入了解:分布式系统中的缓存架构
  12. Solidity 系列教程
  13. Sketch for mac v78 矢量绘图软件
  14. 醉上清新年中工作总结汇报模板免费下载_PPTX图片设计素材_包图网888pic.com
  15. iText API操作doc文档
  16. codeforces1100 F. Ivan and Burgers(线性基)
  17. 高考必胜|东方星书法祝全体考生旗开得胜,金榜题名
  18. 如何成为全栈工程师?
  19. Objective C范型
  20. java解析XML saxReader.read(xml) 错误:org.dom4j.DocumentException: no protocol

热门文章

  1. Embedding在腾讯应用宝的推荐实践
  2. 腾讯云TStack,带着“数据中心”游云南
  3. json中omitempty字段的使用
  4. 大剑无锋之SpringBoot和Spring的区别
  5. 阿里巴巴HBase高可用8年填坑实录
  6. Hadoop的TextInputFormat的作用,如何自定义实现的
  7. Spark _24 _读取JDBC中的数据创建DataFrame/DataSet(MySql为例)(三)
  8. 【Java基础】使用带有标签的break,跳出多层循环
  9. Spring Cloud OpenFeign使用教程
  10. MyBatis3 用log4j在控制台输出 SQL----亲测,真实可用