文档章节

JAVA8-让代码更优雅之List排序

文文1
 文文1
发布于 2018/12/27 13:48
字数 889
阅读 8
收藏 0

先定义一个实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Human {

    private String name;
    private int age;
    
}

下面的操作都基于这个类来进行操作。这里面使用了Lombok类库,它用注解的方式实现了基本的get和set等方法,让代码看起来更加的优雅。

JAVA8之前的List排序操作

在Java8之前,对集合排序只能创建一个匿名内部类

new Comparator<Human>() {
    @Override
    public int compare(Human h1, Human h2) {
        return h1.getName().compareTo(h2.getName());
    }
}

下面是简单的对Humans进行排序(按名称正序)

@Test
public void testSortByName_with_plain_java() throws Exception {

   ArrayList<Human> humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );

   Collections.sort(humans, new Comparator<Human>() {
         
       public int compare(Human h1, Human h2) {
           return h1.getName().compareTo(h2.getName());
       }
   });

   Assert.assertThat(humans.get(0), equalTo(new Human("li", 25)));
}

使用Lambda的List排序

使用JAVA8函数式方式的比较器

(Human h1, Human h2) -> h1.getName().compareTo(h2.getName())

下面是使用JAVA8函数式的比较的例子

@Test
public void testSortByName_with_lambda() throws Exception {

   ArrayList<Human> humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );
   humans.sort((Human h1, Human h2) -> h1.getName().compareTo(h2.getName()));

   Assert.assertThat("tomy", equalTo(humans.get(1).getName()));

}

没有类型定义的排序

对于上面的表达式还可以进行简化,JAVA编译器可以根据上下文推测出排序的类型:

(h1, h2) -> h1.getName().compareTo(h2.getName())

简化后的比较器是这样的:

@Test
public void testSortByNameSimplify_with_lambda() throws Exception {

   ArrayList<Human> humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );
   humans.sort((h1, h2) -> h1.getName().compareTo(h2.getName()));

   Assert.assertThat("tomy", equalTo(humans.get(1).getName()));

}   

使用静态方法引用

JAVA8还可以提供使用Lambda表达式的静态类型引用,我们在Human类增加一个静态比较方法,如下:

public static int compareByNameThenAge(Human h1, Human h2) {

   if (h1.getName().equals(h2.getName())) {
       return Integer.compare(h1.getAge(), h2.getAge());
   }
   return h1.getName().compareTo(h2.getName());
}

然后就可以在humans.sort使用这个引用

@Test
public void testSort_with_givenMethodDefinition() throws Exception {

   ArrayList<Human> humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );
   humans.sort(Human::compareByNameThenAge);
   Assert.assertThat("tomy", is(equalTo(humans.get(1).getName())));
}

使用单独的Comparator

JAVA8已经提供了很多方便的比较器供我们使用,比如Comparator.comparing方法,所以可以使用Comparator.comparing方法来实现根据Human的name进行比较的操作:

@Test
public void testSort_with_givenInstanceMethod() throws Exception {

   ArrayList<Human> humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );

   Collections.sort(humans, Comparator.comparing(Human::getName));
   Assert.assertThat("tomy", equalTo(humans.get(1).getName()));
}

反序

JDK8中也提供了一个支持倒序排序的方法方便我们更快的进行倒序

@Test
public void testSort_with_comparatorReverse() throws Exception {

   ArrayList<Human> humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );

   Comparator<Human> comparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
   humans.sort(comparator.reversed());
   Assert.assertThat("tomy", equalTo(humans.get(0).getName()));

}

使用多个条件进行排序

Lambda提供了更复杂的表达式,还可以先对name排序再根据age进行排序:

@Test
public void testSort_with_multipleComparator() throws Exception {

   ArrayList<Human> humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("li", 25)
   );

   Comparator<Human> comparator = (h1, h2) -> {

       if (h1.getName().equals(h2.getName())) {
           return Integer.compare(h1.getAge(), h2.getAge());
       }
       return h1.getName().compareTo(h2.getName());
   };
   humans.sort(comparator.reversed());
   Assert.assertThat("tomy", equalTo(humans.get(0).getName()));

}

使用多个条件进行排序-组合的方式

Comparator对这种组合的排序有更优雅实现,从JDK8开始,我们可以使用链式操作进行复合操作来构建更复杂的逻辑:

@Test
public void testSort_with_multipleComparator_composition() throws Exception {

   ArrayList<Human> humans = Lists.newArrayList(
           new Human("tomy", 22),
           new Human("tomy", 25)
   );

   humans.sort(Comparator.comparing(Human::getName).thenComparing(Human::getAge));
   Assert.assertThat(humans.get(0), equalTo(new Human("tomy", 22)));

}

总结

JDK8真的是一个非常值得我们学习的版本,它提供了Lambda表达式,带来了函数式编程的理念,让JAVA代码更优雅。
 

本文转载自:https://blog.csdn.net/lanqibaoer/article/details/75036215

共有 人打赏支持
文文1
粉丝 24
博文 391
码字总数 124158
作品 0
长沙
程序员
私信 提问
java8的重要特性及其他,昨天答应的发java8╭(╯ε╰)╮

【注意】本文节选自是 DZone 指南 Java 生态系统的专题文章,作者Trisha Gee是Java资深工程师和布道者。在本文中,Trisha Gee阐述了Java 8的重要特性以及使用的原因,由OneAPM工程师翻译。 ...

默默学习中
2016/03/28
1K
9
java8 (一):为神马要学习java8?

java8新特性 1.1 新特性介绍: 简而言之,java8的新特性就是:Lamdba函数(匿名函数),流,默认方法。 Java8 的灵活使用,会使得代码可读性更好(前提是你的同事也使用,别人不会,你强行使...

AHUSKY
2018/07/14
0
0
为什么选择 Java 8 ?

本文是 DZone 指南 Java 生态系统的专题文章。点击链接可阅读更多见解深刻的文章、行业统计信息,系 OneAPM工程师编译整理。 在很多情况下,Java8 都能提升应用性能,而无需任何改变或性能调...

OneAPM蓝海讯通
2015/11/04
117
0
Java8解决了什么?

在学习面向对象时,许多人都会用Java来举例子,但是其实Java并非纯正的面向对象语言,最明显的就是:int,double等基本类型不是对象。 自从java8出来过后,引入了流,函数式编程,就更不是在向...

MageekChiu
2017/08/02
0
0
java8-lambda实战

前言 java8推出已经很久了,然而其新特性却几乎没有怎么用过。原因是既然已有的只是满足需求何必去学习新的?然而,随着敲代码越来越多,业务上有很多臃肿繁琐的判断校验之类的代码,使得代码...

RyanMiao
2016/11/20
29
0

没有更多内容

加载失败,请刷新页面

加载更多

[walminer bug分析]checkpoint wal记录的lsn与checkpoint记录的redo点的关系

问题背景 walminer工具的用户反馈来一个问题,不管添加了多少wal日志,想要的wal文件的解析结果总是有未解析出的部分。 分析问题 分析问题发现,checkpoint wal记录之后对某个数据page进行修...

movead
41分钟前
4
0
OSChina 周二乱弹 —— 金 冈刂 犭良

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @蓝瞳 :分享骇物乐团的单曲《I'll be the one》: 《I'll be the one》- 骇物乐团 手机党少年们想听歌,请使劲儿戳(这里) @尾生 :工作使人...

小小编辑
47分钟前
293
10
python中类方法和静态方法区别

面相对象程序设计中,类方法和静态方法是经常用到的两个术语。 逻辑上讲:类方法是只能由类名调用;静态方法可以由类名或对象名进行调用。 在C++中,静态方法与类方法逻辑上是等价的,只有一...

xiangyunyan
今天
14
0
Hibernate SQLite方言

以下代码有参考过github上国外某位大佬的,在发文的最新稳定版Hibernate上是可用的,有时间再仔细分析一下 import org.hibernate.dialect.Dialect;import org.hibernate.dialect.function.S...

CHONGCHEN
今天
4
0
CentOS 7 MariaDB搭建主从服务器

本文编写环境为CentOS7。确保关闭SELinux,关闭防火墙或者防打开指定端口。具体信息如下 #master[root@promote ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [r...

白豆腐徐长卿
今天
14
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部