关于使用Lambda表达式简化Comparator的使用问题

目录
  • Comparator 接口
    • 接口简介
      • 定义一个示例类用来演示:Dog类
    • 接口方法介绍
      • 直接使用接口的抽象方法创建 Comparator 对象
    • 接口中的静态方法和默认创建 Comparator 对象
      • comparing 方法(静态)
      • thenComparing 方法(默认)
    • 对于集合中含有 null 值元素的排序
    • 接口中其它方法
      • reversed方法
      • reverseOrder 方法
  • 总结

Comparator 接口

使用集合时,如果需要实现集合元素排序的话,通常有两种选择,元素本身实现 Comparable 接口或者集合使用 Comparator 对象实现排序。这里来介绍一个 Comparator 这个类。

接口简介

Comparator 是一个函数式接口,这个可以从它的定义上看出来。它具有这个注解:@FunctionalInterface

这个注解标注此接口属于函数式接口,意味着只能有一个抽象方法,但是带你进去看,你会发现两个抽象方法!

int compare(T o1, T o2);
boolean equals(Object obj);

这并不是定义错误,而是上面那个注解(@FunctionalInterface)的文档里有说明:如果接口声明了一个覆盖了 java.lang.Object 的全局方法之一的抽象方法,那么它不会计入接口的抽象方法数量中,因为接口的任何实现都将具有 java.lang.Object 或者其它地方的实现。 因此,它确实是只有一个抽象方法:

int compare(T o1, T o2);

定义一个示例类用来演示:Dog类

package com.dragon;

public class Dog {
	private String name;
	private int age;
	private double weight;

	public Dog(String name, int age, double weight) {
		super();
		this.name = name;
		this.age = age;
		this.weight = weight;
	}
	//省略 getter 和 setter 方法,使用 IDE 自动生成比较方便。
	//下面两个方法,也都可以自动生成。

	@Override
	public String toString() {
		return "Dog [name=" + name + ", age=" + age + ", weight=" + weight + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		long temp;
		temp = Double.doubleToLongBits(weight);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Dog other = (Dog) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (Double.doubleToLongBits(weight) != Double.doubleToLongBits(other.weight))
			return false;
		return true;
	}
}

接口方法介绍

这个接口虽然是一个函数式接口,但是它的方法可不少!所以,它可以实现非常丰富的排序功能!

直接使用接口的抽象方法创建 Comparator 对象

**排序规则是按照年龄升序。我这里使用的表达式为:

o1.getAge()-o2.getAge();

如果想要实现反序,调换 o1和o2的位置即可,但是我们不使用这种方式。下面会使用更加方便的方式。
**

1.使用原始的匿名内部类方式,实现 Comparator 对象。

package com.dragon;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class ComparatorTest {
	public static void main(String[] args) {
		//测试使用的集合,下面不再提供,只提供方法的实现。
		List<Dog> dogList = new ArrayList<>();
		dogList.add(new Dog("小黑", 3, 37.0));
		dogList.add(new Dog("二哈", 2, 40.0));
		dogList.add(new Dog("泰迪", 1, 8.0));
		dogList.add(new Dog("大黄", 4, 55.0));
		rawComparator(dogList);
	}

	/**
	 * 原始的实现比较器的方法,使用匿名类
	 * */
	static void rawComparator(List<? extends Dog> dogList) {
		dogList.sort(new Comparator<Dog>() {
			@Override
			public int compare(Dog o1, Dog o2) {
				return o1.getAge()-o2.getAge();
			}
		});
		dogList.forEach(System.out::println);
	}
}

说明:这样显得较为繁琐,不够体现代码的简介,下面使用Java8的 lambda 表达式来改写。

运行结果:

2.使用Java8 的lambda 表达式来简化代码

/**
* 使用lambda的写法
* */
static void lambda(List<? extends Dog> dogList) {
	Comparator<Dog> c = (dog1, dog2)->dog1.getAge() - dog2.getAge();
	dogList.sort(c);
	dogList.forEach(System.out::println);
}

3.舍去中间变量 c,进一步简化代码

/**
 * 舍去中间变量 c 的写法
 * */
static void lambda2(List<? extends Dog> dogList) {
	dogList.sort((dog1, dog2)->dog1.getAge() - dog2.getAge());
	dogList.forEach(System.out::println);
}

总结:基本上,我们第一次接触 lambda 的话,都会去学习写这个表达式,感觉使用起来特别的方便,达到了简化代码的目的。

接口中的静态方法和默认创建 Comparator 对象

comparing 方法(静态)

接口中有一个静态方法 comparing,使用起来也特别的方便,基本上可以代替上面的那种方式了,它的参数为:Function<? super T, ? extends U> keyExtractor,这需要传入一个 lambda 表达式。虽然这些方法的定义很复杂,但是使用起来却感觉很简单,复杂的事情都被别人做了。

comparing 方法源码

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
{
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

1.使用 comparing方法创建 Comparator 对象

/**
 * 使用 Java 8 提供的静态方法 comparing 方法,
 * 再配合方法引用,写法更加简洁了。但是看这个
 * 方法,我们可能会疑问排序顺序到底是正序还是逆序呢?
 * */
static void lambda3(List<? extends Dog> dogList) {
	dogList.sort(Comparator.comparing(Dog::getAge));
	dogList.forEach(System.out::println);
}

说明: 通过上面的源码可以看到,c1 和 c2 的位置是固定的(排序是固定的升序方式),它是通过 Function 接口,调用apply方法,生成一个对象,然后调用 compareTo 方法进行比较的。(例如,我们传进去的是age,类型为int,但是通过apply会返回 Integer类型。因为包装类型和 String 类都实现了 Comparable 接口。)

注意: 如果不使用方法引用的话,那么 Dog::getAge 应该被替换为:

(dog1, dog2)->dog1.getAge() - dog2.getAge()

不过,这样做显然就是去了简介性。

2.使用重载的 comparing 方法创建 Comparator 对象

comparing 方法源码

 public static <T, U> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
 {
     Objects.requireNonNull(keyExtractor);
     Objects.requireNonNull(keyComparator);
     return (Comparator<T> & Serializable)
         (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                           keyExtractor.apply(c2));
 }

说明: 它比上面的 comparing 方法多了一个参数,意味着它可以实现更丰富的比较操作。而且,这个参数也是一个 Comparator 对象。

好了,下面使用这个方法,来实现按照年龄逆序排序。

/**
 * 解决 lambda3 中的疑问,关于排序顺序的问题。
 * 上面那个方法是一个简便方法,它的排序是默认的正序,
 * 而我们有时会希望逆序排序。所以我们需要使用它的一个重载方法了。
 * */
static void lambda4(List<? extends Dog> dogList) {
	//它的第二个参数,可能会引起困惑,第二个参数的类型就是第一个参数指定的类型(如果是基本类型,则为对应的包装类)
	dogList.sort(Comparator.comparing(Dog::getAge, (age1, age2)->age2-age1));
	dogList.forEach(System.out::println);
}

注意: 这里的第二个参数中的 age1 和 age2 的实际类型为 Integer而不是 int,可以直接相减的原因是因为自动拆箱机制,所以这里推荐更换为:

说明: 这样看起来,似乎不够简洁,下面将使用更加简洁的方式来实现逆序排序。

(age1, age2)->age2.compareTo(age1)

运行结果:

3.使用comparing方法的更加简洁形式
Comparator 具有一个静态的方法,它的功能很简单就是逆序。

/**
 * 相信看完 lambda4 都会感觉还没有 lambda2 的方式简洁呢,
 * 但是因为正序和逆序只是一个变换顺序的问题,所以它也提
 * 供了简洁的实现。当然了,这也与我这里的使用的Dog对象,比较简单有关,
 * 只看这里的话, 和上面 lambda2 进行比较,优势不太明显。
 * */
static void lambda5(List<? extends Dog> dogList) {
	dogList.sort(Comparator.comparing(Dog::getAge, Comparator.reverseOrder()));
	dogList.forEach(System.out::println);
}

这样,代码就显得简洁多了,当然了,还可以使用一个默认方法当到同样的目的。

/**
 * 这样也可以
 * */
static void lambda55(List<? extends Dog> dogList) {
	dogList.sort(Comparator.comparing(Dog::getAge).reversed());
	dogList.forEach(System.out::println);
}

thenComparing 方法(默认)

thenComparing 方法源码:

default <U extends Comparable<? super U>> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor)
{
    return thenComparing(comparing(keyExtractor));
}

有时候,会碰到这样的需求,需要使用多种排序方法,而不是单纯的一种。例如使用:姓名、年龄、体重进行排序。这时就需要使用 thenComparing 方法了。

/**
 * 实现按照多个标准排序:姓名、年龄、体重
 * 全部按照自然排序(升序)的顺序
 * */
static void lambda7(List<? extends Dog> dogList) {
	dogList.sort(Comparator
			.comparing(Dog::getName)
			.thenComparing(Dog::getAge)
			.thenComparing(Dog::getWeight));
	dogList.forEach(System.out::println);
}

说明1: 这里按照三个条件排序是指如果姓名相同了,再按照下一个排序,以此类推,所以你可能看不出来差别(这个结果和按照姓名排序一样,主要是排序的数据不太适合,但我不想换了。)。

说明2: 你仍然可以继续添加更多的排序规则,因为 thenComparing 方法也有重载的方法。

运行结果:

thenComparing 方法的重载方法源码:

 default <U> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
 {
     return thenComparing(comparing(keyExtractor, keyComparator));
 }

它的第二个方法,也和上面的 comparing 方法作用相同,是自己实现一个key的比较器,这里就不再说明了。

适用于 Int、long 和 double 类型的 thenComapring 方法

default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
    return thenComparing(comparingInt(keyExtractor));
}

default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
    return thenComparing(comparingLong(keyExtractor));
}  

default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
    return thenComparing(comparingDouble(keyExtractor));
}

说明:这几个方法和上面的 thenComparing 方法作用基本相同,但是更加适合处理 int、long和double类型。如果需要排序的类型为这几个,使用这些方法很好,但是我还是喜欢通用的 thenComparing 方法,这里只演示一个 thenComparingDouble 方法:

static void thenComparingDouble() {
	List<Dog> dogList = new ArrayList<>();
	dogList.add(new Dog("小黑", 3, 37.0));
	dogList.add(new Dog("二哈", 2, 55.0));
	dogList.add(new Dog("泰迪", 1, 8.0));
	dogList.add(new Dog("大黄", 2, 40.0));

	dogList.sort(Comparator
			.comparing(Dog::getAge)
			.thenComparingDouble(Dog::getWeight));
	dogList.forEach(System.out::println);
}

运行结果:

如果去掉 thenComparingDouble 方法,运行结果为:
注意和上面的结果对比。

适用于 Int、long 和 double 类型的 comapring 方法

这三个方法,也是专门用于处理 int、long 和double类型的,和使用 comparing方法差不多。

public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
        Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
}

 public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
     Objects.requireNonNull(keyExtractor);
     return (Comparator<T> & Serializable)
         (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
 }

public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
}

这里演示 comparingIntcomparingDouble 两个方法的用法:
我感觉没什么区别,可能是我这个测试用例太简单了吧。

/**
 * comparingToInt
 * */
static void comparingToInt(List<? extends Dog> dogList) {
	dogList.sort(Comparator.comparingInt(Dog::getAge));
	dogList.forEach(System.out::println);
}

/**
 * comparingToDouble
 * */
static void comparingToDouble(List<? extends Dog> dogList) {
	dogList.sort(Comparator.comparingDouble(Dog::getWeight));
	dogList.forEach(System.out::println);
}

对于集合中含有 null 值元素的排序

static void nullSort() {
		List<String> strList = new ArrayList<>();
		strList.add("dog");
		strList.add("cat");
		strList.add(null);
		strList.add("Bird");
		strList.add(null);

		strList.sort(Comparator.comparing(String::length));
		strList.forEach(System.out::println);
	}

运行上面的代码,结果为:

说明:null 值是一个很头疼的问题,所以 Comparator接口也专门提供了处理null值得方法,它们都是对 null 值友好的方法(null-friendly)。

//null 值在前面。
//Returns a null-friendly comparator that considers null to be less than non-null.
 public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
     return new Comparators.NullComparator<>(true, comparator);
 }

//null 值在后面。
//Returns a null-friendly comparator that considers null to be greater than non-null.
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
    return new Comparators.NullComparator<>(false, comparator);
}

因此,对于含有null值的元素进行排序,可以这样做:

/**
 * 含有 null 值得元素排序
 * */
public static void nullValueSort() {
	List<String> strList = new ArrayList<>();
	strList.add("dog");
	strList.add("cat");
	strList.add(null);
	strList.add("Bird");
	strList.add(null);
	//我一开始以为是一个字符常量呢?但是一想不对劲,原来是一个静态常量比较器。
	//这个是 String 类的比较器:CASE_INSENSITIVE_ORDER
	//null 值在前排序
	strList.sort(Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER));
	strList.forEach(System.out::println);
	System.out.println("===================分隔符====================");
	//null 值在后排序
	strList.sort(Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER));
	strList.forEach(System.out::println);
}

运行结果:
注:摆脱了,烦人的NullPointerException,哈哈。

接口中其它方法

reversed方法

in other words, it returns a comparator that imposes the reverse of the natural ordering on a collection of objects that implement the Comparable interface。
换言之,它返回一个比较器,该比较器对实现可比较接口的对象集合施加与自然顺序相反的顺序。

说明: 由于它是默认方法,所以必须由比较器对象本身来调用,正好可以实现逆序操作。可以在创建比较器后继续调用这个方法,就可以实现逆序了。但是要注意它调用的顺序,它和下面这个 reverseOrder 方法还是不一样的,下面这个方法是静态方法,可以通过类直接调用。注意,用法上的区别就是了。

 default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
 }

reverseOrder 方法

public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
    return Collections.reverseOrder();
}

如果直接使用这个方法,创建比较器对象的话,那么集合里面的元素必须使用 Comparable 接口。

static void reverseSort() {
	List<String> strList = new ArrayList<>();
	strList.add("dog");
	strList.add("cat");
	strList.add("Bird");

	strList.sort(Comparator.reverseOrder());
	strList.forEach(System.out::println);
}

注意:这里有一个很有趣的地方,这个方法Comparator.reverseOrder()无法使用方法引用改写:Comparator::reverseOrder,具体原因我看了,但是不是太理解,就不说了。

运行结果:

补充: 晚上思考了一下,结合别人的答案,这里其实也是不难理解的。自所以不能使用方法引用,是因为它根本就不是 lambda 表达式。Lambda 表达式需要依赖一个函数式接口,也就是 Comparator 接口。它的作用就是一个简化,所以它的需要的参数就是 int compare(T o1, T o2); 的方法中的参数。

所以,如果这样写的话,会报一个错误。
The type Comparator does not define reverseOrder(String, String) that is applicable here

strList.sort(Comparator::reverseOrder);

因此,上面这个写法就是错误的了。它并不能使用lambda的形式改写。

reverseOrder 和 reversed联合使用

	static void reverseSort() {
		List<String> strList = new ArrayList<>();
		strList.add("dog");
		strList.add("cat");
		strList.add("Bird");

		Comparator c = Comparator.reverseOrder().reversed();
		strList.sort(c);
		strList.forEach(System.out::println);
	}

说明:上面这个例子我不会添加泛型了,我无论怎么添加都是错误的,但是如果不添加泛型的话,那么编译就能通过了。但是这个东西的泛型似乎很奇怪,我也不太明白了,但是这个方法很有趣,反序的反序又是正序了。(这里存粹是娱乐一下,但是好像发现了好玩的东西。)

运行结果:

naturalOrder

定制排序里面居然有一个方法名叫做自然排序,这个方法感觉很有趣。但是使用的话,需要抑制一下 unchecked 警告。

@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
    return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}

方法注释里面说明了:

@param  <T> the {@link Comparable} type of element to be compared。

参数必须是 Comparable类型的,即实现 Comparable 接口。

自然排序:

/**
 * Comparator 实现自然排序
 * */
@SuppressWarnings("unchecked")
static void lambda6(List<? extends Dog> dogList) {
	dogList.sort((Comparator<Dog>) Comparator.naturalOrder());
	dogList.forEach(System.out::println);
}

如果直接运行这个方法会产生问题,必须要先实现 Comparable接口才行,并重写 compareTo方法。

@Override
public int compareTo(Dog o) {
	return age-o.age;
}

运行结果:

说明:不太明白,安排这个方法的目的何在,感觉很奇怪。

总结

大致介绍了一下 Comparator 接口中的方法,并写了很多演示方法。写这篇博客的起因是我用到 Comparator 接口的时候,感觉似乎有很多丰富的方法,似乎怎么写都行(哈哈),所以干脆一劳永逸,抽时间看一看这个 Comparator 到底怎么写,发现确实是很有趣的。

到此这篇关于关于使用Lambda表达式简化Comparator的使用问题的文章就介绍到这了,更多相关Lambda表达式简化Comparator内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java Lambda表达式详解

    Java Lambda表达式是JDK8引入的,是一个比较重要的特性 Lambda表达式简介 Lambda 表达式是 JDK8 的一个新特性,也被称为闭包,Lambda表达式允许把函数作为一个方法的参数,即行为参数化,函数作为参数传递进方法中. Lambda表达式可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构. Lambda表达式的作用 Java 8 引入的 Lambda表达式的主要作用就是简化代码,写出更优雅的代码. 怎么一个简

  • C++ lambda函数详解

    目录 Lambda 表达式 基础 1. 值捕获 2. 引用捕获 3. 隐式捕获 4. 表达式捕获 泛型 Lambda 函数对象包装器 Lambda 表达式 Lambda 表达式是现代 C++ 中最重要的特性之一,而 Lambda 表达式,实际上就是提供了一个类似匿名函数的特性, 而匿名函数则是在需要一个函数,但是又不想费力去命名一个函数的情况下去使用的.这样的场景其实有很多很多, 所以匿名函数几乎是现代编程语言的标配. 基础 Lambda 表达式的基本语法如下: [捕获列表](参数列表) mut

  • Java8如何使用Lambda表达式简化代码详解

    系统环境: Java JDK 版本:1.8 参考地址: Java 8 Lambda 表达式 Jdk 8 新特性 04 方法引用与构造器引用 Java 8 新特性:Lambda 表达式之方法引用 一.Lambda 表达式简介 1.什么是 Lambda 表达式 Lambda 表达式是在 JDK 8 中引入的一个新特性,可用于取代大部分的匿名内部类.使用 Lambda 表达式可以完成用少量的代码实现复杂的功能,极大的简化代码代码量和代码结构.同时,JDK 中也增加了大量的内置函数式接口供我们使用,使得

  • Java编程中使用lambda表达式的奇技淫巧

    为什么使用Lambda表达式 先看几个例子: 第一个例子,在一个独立的线程中执行某项任务,我们通常这么实现: class Worker implements Runnable { public void run() { for (int i = 0; i < 100; i++) doWork(); } ... } Worker w = new Worker(); new Thread(w).start(); 第二个例子,自定义字符串比较的方法(通过字符串长度),一般这么做: class Leng

  • Java 进阶使用 Lambda 表达式实现超强的排序功能

    目录 基于Comparator排序 使用 Lambda 表达式替换Comparator匿名内部类 通过静态方法抽取公共的 Lambda 表达式 借助Comparator的comparing方法 多条件排序 在Stream中进行排序 倒序排列 调转排序判断 在Comparator.comparing中定义排序反转 在Stream中定义排序反转 null 值的判断 元素是 null 的笨拙实现 排序条件的字段是 null 文末总结 我们在系统开发过程中,对数据排序是很常见的场景.一般来说,我们可以采

  • Java Lambda表达式详解和实例

    简介 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块). Lambda表达式还增强了集合库. Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及 java.util.stream 包. 流(stream)就如同迭代器(iterator),但附加了许多额外的功能.

  • Java8 新特性Lambda表达式实例详解

    Java8 新特性Lambda表达式实例详解 在介绍Lambda表达式之前,我们先来看只有单个方法的Interface(通常我们称之为回调接口): public interface OnClickListener { void onClick(View v); } 我们是这样使用它的: button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { v.setText("

  • Java8新特性之Lambda表达式浅析

    说到java 8,首先会想到lambda(闭包)以及虚拟扩展方法(default method),这个特性早已经被各大技术网站炒得沸沸扬扬了,也是我们java 8系列开篇要讲的第一特性(JEP126 http://openjdk.java.net/jeps/126),jdk8的一些库已经应用了lambda表达式重新设计了,理解他对学习java 8新特性有着重要的意义. 一.函数式接口 函数式接口(functional interface 也叫功能性接口,其实是同一个东西).简单来说,函数式接口是

  • Java8学习教程之lambda表达式语法介绍

    前言 相信大家都知道,在Java8 中引入了 lambda 表达式,从行为参数化的角度,在使用时,将行为作为参数,去除包围在外层的不必要的类声明,使代码更加简洁. lambda 表达式的语法 lambda 表达式由参数,->,以及函数体三部分组成.其实函数体可以是表达式,也可以是语句.语句应该包含在{} 里,而表达式不能. lambda 表达式举例 (List<String> list) -> list.isEmpty() // 布尔类型表达式 () -> new Apple

  • Java 8 lambda表达式引入详解及实例

    Java 8 lambda表达式引入详解及实例 eclipse 下载安装 Help -> EclipseMarketplace -> 搜索Java 8 Kepler ->Java 8 support for eclipse Kepler SR2 安装完成后需要重启 Android Studio 在project的build.gradle文件中添加 buildscript { dependencies { classpath 'me.tatarka:gradle-retrolambda:3

  • Java Lambda 表达式详解及示例代码

    Java Lambda 表达式是 Java 8 引入的一个新的功能,可以说是模拟函数式编程的一个语法糖,类似于 Javascript 中的闭包,但又有些不同,主要目的是提供一个函数化的语法来简化我们的编码. Lambda 基本语法 Lambda 的基本结构为 (arguments) -> body,有如下几种情况: 参数类型可推导时,不需要指定类型,如 (a) -> System.out.println(a) 当只有一个参数且类型可推导时,不强制写 (), 如 a -> System.o

  • 深入浅析JDK8新特性之Lambda表达式

    第一次是接触Lambda表达式是在TypeScript中(JavaScript的超集中),当时是为了让TypeScript的this方法外而不是本方法内所使用的.使用过后突然想到Lambda不是JDK8的重量级新特性么?于是感觉查阅相关资料并记录下来: 一. 行为参数化 行为参数化简单的说就是函数的主体仅包含模板类通用代码,而一些会随着业务场景而变化的逻辑则以参数的形式传递到函数之中,采用行为参数化可以让程序更加的通用,以应对频繁变更的需求. 考虑一个业务场景,假设我们需要通过程序对苹果进行筛选

随机推荐