Let's learn Java8 together (4) - compound Lambda

In 一起来学Java8(二)——Lambda表达式, we learned the basic usage of lambda expressions, now let's understand compound lambdas.

The writing of Lambda expressions is inseparable from the functional interface. Composite Lambda means that after using the Lambda expression to implement the abstract method of the functional interface, other methods of the interface can be called again, because starting from Java8, the interface can contain default values. method to implement. The 接口默认实现方法details will be explained in the following chapters.

Common composite Lambdas are the following categories:

  • Comparator composition, corresponding functional interface: Comparator
  • Predicate composition, corresponding functional interface: Predicate
  • Function composition, corresponding functional interface: Function

Comparator Composite

Let's first look at the common usage of the Comparator interface, and sort the commodity prices from low to high

package learn.java8.ch4;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

class Goods {
	private String name;
	private int price;

	public Goods(String name, int price) {
		super();
		this.name = name;
		this.price = price;
	}

    省略get set
}

public class ComparatorTest {

	public static void main(String[] args) {
		List<Goods> list = Arrays.asList(
				new Goods("mete30", 3999),
				new Goods("mete30 pro", 4999),
				new Goods("redmi k20", 2999),
				new Goods("iqoo", 2999),
				new Goods("iphone11", 5000)
				);
		
		Comparator<Goods> comparatorForPrice = (Goods goods1, Goods goods2) -> {
			return Integer.compare(goods1.getPrice(), goods2.getPrice());
		};
		list.sort(comparatorForPrice);
		System.out.println(list);
	}
}

Here is the order according to the price from low to high, we can add another demand, if the price is the same, then sort according to the product name. Then the code can be written like this:

public static void main(String[] args) {
		List<Goods> list = Arrays.asList(new Goods("mete30", 3999), new Goods("mete30 pro", 4999),
				new Goods("redmi k20", 2999), new Goods("iqoo", 2999), new Goods("iphone11", 5000));

		Comparator<Goods> comparatorForPrice = (Goods goods1, Goods goods2) -> {
			return Integer.compare(goods1.getPrice(), goods2.getPrice());
		};

		Comparator<Goods> comparatorForName = (Goods goods1, Goods goods2) -> {
			return goods1.getName().compareTo(goods2.getName());
		};
		
		// 把两个函数式接口进行复合,组成一个新的接口
		Comparator<Goods> finalComparator = comparatorForPrice.thenComparing(comparatorForName);
		list.sort(finalComparator);
		System.out.println(list);
	}

The above example Comparator<Goods> finalComparator = comparatorForPrice.thenComparing(comparatorForName);is the embodiment of compound lambda expressions. The thenComparing() method is a default implementation method of the Comparator interface.

Predicate Compounding

Predicate compounding is implemented using the predicate function interface. The predicate interface is defined as follows:

@FunctionalInterface
public interface Predicate<T> {
  
    // 抽象接口,判断是否为真
    boolean test(T t);
    
    // 默认方法,跟另一个谓词一起判断
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    //  默认方法,判断后进行非操作
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    // 默认方法,跟另一个谓词一起判断
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
    
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

Let's take a look at a specific example:

package learn.java8.ch4;

import java.util.function.Predicate;

public class PredicateTest2 {
	static class Goods {
		private String name;
		// 价格
		private int price;
		// 库存
		private int storeCount;

		public Goods(String name, int price, int storeCount) {
			super();
			this.name = name;
			this.price = price;
			this.storeCount = storeCount;
		}
	}

	public static void main(String[] args) {
		Goods mete30pro = new Goods("mete30 pro", 4999, 111);
		Goods iphone11 = new Goods("iphone11", 5000, 444);

		Predicate<Goods> predicate = (goods) -> goods.price > 4000;

		System.out.println("mete30pro价格是否大于4000:" + predicate.test(mete30pro));

		Predicate<Goods> predicatePrice = (goods) -> goods.price > 6000;
		Predicate<Goods> predicateStore = (goods) -> goods.storeCount > 400;
		// 价格大于6000或库存大于400
		Predicate<Goods> predicateOr = predicatePrice.or(predicateStore);
		System.out.println("价格大于6000或库存大于400:" + predicateOr.test(iphone11));
	}

}

function composition

Function composition java.util.function.Functionis implemented using functional interfaces.

The Function interface is defined as follows:

// 两个泛型参数,T表示入参类型,R表示返回类型
@FunctionalInterface
public interface Function<T, R> {

    // 抽象方法
    R apply(T t);

    // 默认实现方法,先执行before,将结果带入当前apply方法中执行
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    // 按顺序执行,先执行当前apply函数,再执行指定的after.apply函数
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    // 辅助方法,始终返回入参值
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

It is easy to understand from the code. Next, let's list a few simple examples. First, let's look at the use of the andThen method:

private static void test1() {
    Function<Integer, Integer> funMultiply = (input) -> input * 2;
    Function<Integer, Integer> funMinus = (input) -> input - 1;
    // input * 2 - 1
    Function<Integer, Integer> finalFun = funMultiply.andThen(funMinus);

    Integer result = finalFun.apply(2);
    System.out.println(result); // 3
}

This example defines two functions, one that multiplies the arguments and returns, and one that subtracts the arguments and returns. Then use the andThen method to concatenate the two functions. Mathematically expressed as:2 * 2 - 1

Next is the compose example:

private static void test2() {
    Function<Integer, Integer> funMultiply = (input) -> input * 2;
    Function<Integer, Integer> funMinus = (input) -> input - 1;

    // (input - 1) * 2
    Function<Integer, Integer> finalFun = funMultiply.compose(funMinus);

    Integer result = finalFun.apply(2);
    System.out.println(result); // 2
}

Here, the subtraction is performed first, the result obtained is passed in, and then the multiplication operation is performed. Mathematically expressed as:(2 - 1) * 2

Regularly share technical dry goods, learn together, and progress together!

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324090482&siteId=291194637