list元素排序需要满足两个条件
关于List
说到list,我的印象就是单值集合接口,插入取出是有序的,允许重复,用他的实现类用的最频繁的就是ArrayList了。如果我现在有一个list,插入了一些值,想让里面的值按照我自定义的规则排序。
以下测试基于JDK1.7
①list里面是String的情况
public static void main(String[] args) {
List<String> listStrs = new ArrayList<String>();
listStrs.add("aba");
listStrs.add("aba2111");
listStrs.add("aba22");
for (String s : listStrs) {
System.out.println(s);
}
Collections.sort(listStrs); //排序操作
System.out.println("操作后");
for (String s : listStrs) {
System.out.println(s);
}
}
console:
aba
aba2111
aba22
操作后
aba
aba2111
aba22
从打印结果可以看出,collections.sort(listStrs);是排序了的,看下sort方法的源码
public static <T extends Comparable<? super T>> void sort(List<T> list) {
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set((T)a[j]);
}
}
实际上就是把list转成数组,再执行Arrays.sort(a); sort源码就不看了,我简单跟了一下,实际上它是调用了ComparableTimSort.sort方法,继续跟下去最终会把数组a 转换成 Comparable接口:Comparable<Object> pivot = (Comparable) a[start];,到这里就可以解释为什么String类实现了Comparable接口;
下面是跟踪Arrays.sort(a)的源码

接下来看看String实现了Comparable接口,是怎么实现它里面唯一的方法的
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
这个方法就是定义了排序的规则,返回负数则调换这两个数的顺序,返回正数和0不管,所以从代码中可以看到优先比较字符串中的字符大小,然后比较长度,这就是String的排序规则。
② list里面是普通实体类Person的情况
public class Person{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.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 String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Test
public void fun1() {
List<Person> listStrs = new LinkedList<Person>();
listStrs.add(new Person("zhangsan", 20));
listStrs.add(new Person("lisi", 28));
listStrs.add(new Person("wangwu", 24));
for (Person p : listStrs) {
System.out.println(p);
}
System.out.println("我排序之后:");
Collections.sort(listStrs, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.age - p2.age;
}
});
for (Person p : listStrs) {
System.out.println(p);
}
}
我采用的是new Comparator()的方式才定义排序规则,规则比较简单,就是按照年龄升序
也可以让Person类和String类玩一个套路,让他实现Comparable接口。
public class Person<T> implements Comparable<T>{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.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 String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(T o) {
if(o instanceof Integer) {
return (Integer)o - age;
}
if(o instanceof Person) {
System.out.println("是啥:" + ((Person) o).getAge() + "this是啥:" + this.getAge());
return this.age - ((Person) o).getAge();
}
return 0;
}
}
@Test
public void fun2() {
List<Person> listStrs = new LinkedList<Person>();
listStrs.add(new Person("zhangsan", 20));
listStrs.add(new Person("lisi", 28));
listStrs.add(new Person("wangwu", 24));
for (Person p : listStrs) {
System.out.println(p);
}
System.out.println("我排序之后:");
Collections.sort(listStrs);
for (Person p : listStrs) {
System.out.println(p);
}
}
总结:
1 list默认是存取是有序的。
2 要想让List按照自己定义的规则进行排序,需满足两点:① list中的元素实现Comparable接口,② Collections.sort(list)方法
2 String类实现了Comparable接口,规则是按照字符串长度和字母a-z升序排序。
list元素排序需要满足两个条件的更多相关文章
- 《Algorithms算法》笔记:元素排序(1)——简单排序
<Algorithms算法>元素排序(1)——简单排序 Algorithms算法元素排序1简单排序 排序问题 1 回调函数 2Java中回调函数的路线图 3 全序 4 Comparable ...
- Python对列表中字典元素排序
问题起源 json对象a,b a = '{"ROAD": [{"id": 123}, {"name": "no1"}]} ...
- PAT 甲级 1053 Path of Equal Weight (30 分)(dfs,vector内元素排序,有一小坑点)
1053 Path of Equal Weight (30 分) Given a non-empty tree with root R, and with weight Wi assigne ...
- Python小白干货宝典:sorted()函数:列表元素排序
定义: sorted() 函数对所有可迭代的对象进行排序操作. 内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作. 语法: sorted 语法: sorted(i ...
- H5 60-浮动元素排序规则
60-浮动元素排序规则 <!DOCTYPE html><html lang="en"><head> <meta charset=" ...
- Python对List中的元素排序
首先定义一个compare函数: def compare(sf1, sf2): if (sf1.value > sf2.value): return -1; elif (sf1.value == ...
- Atitit 如何创新 创新只有在两种条件下发生:自由、效率。
Atitit 如何创新 创新只有在两种条件下发生:自由.效率. 创新是如何发生的呢? 创新只有在两种条件下发生:自由.效率.在自由的环境下,对效率的追逐等于创新.如果你不自由,你的思想不够开阔,你脑洞 ...
- SortedSet的实现类是TreeSet:它的作用是字为添加到TreeSet中的元素排序。
SortedSet可自动为元素排序. SortedSet的实现类是TreeSet:它的作用是字为添加到TreeSet中的元素排序. 练习:自定义类用TreeSet排序. 与HashSet不同, ...
- 《Algorithms算法》笔记:元素排序(4)——凸包问题
<Algorithms算法>笔记:元素排序(4)——凸包问题 Algorithms算法笔记元素排序4凸包问题 凸包问题 凸包问题的应用 凸包的几何性质 Graham 扫描算法 代码 凸包问 ...
随机推荐
- GO函数总结(转)
GO语言函数与C,JAVA等有点很大的区别,大致如下: 一.函数的定义 例如: func max(a, b int) int{//返回a,b里面最大的一个,而且要注意函数的参数和返回值类型是怎么定义的 ...
- 二 Android Studio 打包EgretApp (开机画面、横竖屏、调试、和原生交互)
测试环境: Windows7 Egret Engine 5.0.14 Egret support 5.0.12 Android Studio 2.3 目录: 一 修改开机画面 二 横竖屏设置 三 修改 ...
- ios 将图片做成圆形
UIImageView * imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"oiuyfdsa.png ...
- Hibernate的大对象映射
1在持久类中直接声明是java.sql.Blob类型 2在.hbm.xml文件中配置一下信息 <!-- 映射大对象 (就是字符长度超过255和图片想转换成二进制的数据)--> <!- ...
- oracle导入sql文件
oracle导入sql文件: 1.进入到sql文件目录下,登录需要导入文件的用户 打开cmd,输入以下命令,进入oracle, sqlplus username/password username:需 ...
- Spring 拦截器的使用
一.Web.xml配置 在Web.xml 配置Spring核心控制器DispatcherServlet接收所有请求 <servlet> <servlet-name>spring ...
- 使用Ansible自动配置Nginx服务
1.首先安装好Ansible环境,具体步骤请见Ansible安装 2.先创建hosts文件(为后面编写脚本安装JDK做铺垫) [root@localhost /]# vi hosts [jdktest ...
- 第十一课——codis-server的高可用,对比codis和redis cluster的优缺点
[作业描述] 1.配置codis-ha 2.总结对比codis的集群方式和redis的cluster集群的优缺点 =========================================== ...
- llvm,gcc
GCC,LLVM,Clang编译器对比 在XCode中,我们经常会看到这些编译选项(如下图),有些人可能会有些茫然,本文将对GCC4.2.LLVM GCC 4.2.LLVM compliler 2 ...
- golang处理 json中非法字符
原文: Hi there, I just discovered Go and decided to port a little program to Go. The program reads JSO ...