Java自学-Lambda 方法引用

Lambda 方法引用

步骤 1 : 引用静态方法

首先为TestLambda添加一个静态方法:

public static boolean testHero(Hero h) {
   return h.hp>100 && h.damage<50;
}

Lambda表达式:

filter(heros, h->h.hp>100 && h.damage<50);

在Lambda表达式中调用这个静态方法:

filter(heros, h -> TestLambda.testHero(h) );

调用静态方法还可以改写为:

filter(heros, TestLambda::testHero);

这种方式就叫做引用静态方法

package lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import charactor.Hero;

public class TestLambda {
    public static void main(String[] args) {
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 5; i++) {
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
        System.out.println("初始化后的集合:");
        System.out.println(heros);

        HeroChecker c = new HeroChecker() {
            public boolean test(Hero h) {
                return h.hp>100 && h.damage<50;
            }
        };

        System.out.println("使用匿名类过滤");
        filter(heros, c);
        System.out.println("使用Lambda表达式");
        filter(heros, h->h.hp>100 && h.damage<50);
        System.out.println("在Lambda表达式中使用静态方法");
        filter(heros, h -> TestLambda.testHero(h) );
        System.out.println("直接引用静态方法");
        filter(heros, TestLambda::testHero);
    }

    public static boolean testHero(Hero h) {
        return h.hp>100 && h.damage<50;
    }

    private static void filter(List<Hero> heros, HeroChecker checker) {
        for (Hero hero : heros) {
            if (checker.test(hero))
                System.out.print(hero);
        }
    }

}

步骤 2 : 引用对象方法

与引用静态方法很类似,只是传递方法的时候,需要一个对象的存在

TestLambda testLambda = new TestLambda();
filter(heros, testLambda::testHero);

这种方式叫做引用对象方法

package lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import charactor.Hero;

public class TestLambda {
    public static void main(String[] args) {
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 5; i++) {
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
        System.out.println("初始化后的集合:");
        System.out.println(heros);

        System.out.println("使用引用对象方法  的过滤结果:");
        //使用类的对象方法
        TestLambda testLambda = new TestLambda();
        filter(heros, testLambda::testHero);
    }

    public boolean testHero(Hero h) {
        return h.hp>100 && h.damage<50;
    }

    private static void filter(List<Hero> heros, HeroChecker checker) {
        for (Hero hero : heros) {
            if (checker.test(hero))
                System.out.print(hero);
        }
    }

}

步骤 3 : 引用容器中的对象的方法

首先为Hero添加一个方法

public boolean matched(){
   return this.hp>100 && this.damage<50;
}

使用Lambda表达式

filter(heros,h-> h.hp>100 && h.damage<50 );

在Lambda表达式中调用容器中的对象Hero的方法matched

filter(heros,h-> h.matched() );

matched恰好就是容器中的对象Hero的方法,那就可以进一步改写为

filter(heros, Hero::matched);

这种方式就叫做引用容器中的对象的方法

package lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import charactor.Hero;

public class TestLambda {
    public static void main(String[] args) {
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 5; i++) {
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
        System.out.println("初始化后的集合:");
        System.out.println(heros);

        System.out.println("Lambda表达式:");
        filter(heros,h-> h.hp>100 && h.damage<50 );

        System.out.println("Lambda表达式中调用容器中的对象的matched方法:");
        filter(heros,h-> h.matched() );

        System.out.println("引用容器中对象的方法 之过滤结果:");
        filter(heros, Hero::matched);
    }

    public boolean testHero(Hero h) {
        return h.hp>100 && h.damage<50;
    }

    private static void filter(List<Hero> heros, HeroChecker checker) {
        for (Hero hero : heros) {
            if (checker.test(hero))
                System.out.print(hero);
        }
    }

}

步骤 4 : 引用构造器

有的接口中的方法会返回一个对象,比如java.util.function.Supplier提供
了一个get方法,返回一个对象。

public interface Supplier<T> {
    T get();
}

设计一个方法,参数是这个接口

public static List getList(Supplier<List> s){
  return s.get();
}

为了调用这个方法,有3种方式
第一种匿名类:

Supplier<List> s = new Supplier<List>() {
    public List get() {
        return new ArrayList();
    }
};
List list1 = getList(s);

第二种:Lambda表达式

List list2 = getList(()->new ArrayList());

第三种:引用构造器

List list3 = getList(ArrayList::new);

.

package lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class TestLambda {
    public static void main(String[] args) {
    Supplier<List> s = new Supplier<List>() {
        public List get() {
            return new ArrayList();
        }
    };

    //匿名类
    List list1 = getList(s);

    //Lambda表达式
    List list2 = getList(()->new ArrayList());

    //引用构造器
    List list3 = getList(ArrayList::new);

    }

    public static List getList(Supplier<List> s){
        return s.get();
    }

}

练习引用构造器

把比较ArrayList和LinkedList的区别这段代码,改造成引用构造器的模式。
目前的调用方式是:

    List<Integer> l;
    l = new ArrayList<>();
    insertFirst(l, "ArrayList");

    l = new LinkedList<>();
    insertFirst(l, "LinkedList");

改造后的调用方式将变为:

    insertFirst(ArrayList::new, "ArrayList");
    insertFirst(LinkedList::new, "LinkedList");
package collection;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class TestCollection {
    public static void main(String[] args) {
        List<Integer> l;
        l = new ArrayList<>();
        insertFirst(l, "ArrayList");

        l = new LinkedList<>();
        insertFirst(l, "LinkedList");

    }

    private static void insertFirst(List<Integer> l, String type) {
        int total = 1000 * 100;
        final int number = 5;
        long start = System.currentTimeMillis();
        for (int i = 0; i < total; i++) {
            l.add(0, number);
        }
        long end = System.currentTimeMillis();
        System.out.printf("在%s 最前面插入%d条数据,总共耗时 %d 毫秒 %n", type, total, end - start);
    }

}

答案

package collection;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Supplier;

public class TestCollection {
    public static void main(String[] args) {
        insertFirst(ArrayList::new, "ArrayList");
        insertFirst(LinkedList::new, "LinkedList");
    }

    private static void insertFirst(Supplier<List> s, String type) {
        int total = 1000 * 100;
        final int number = 5;
        long start = System.currentTimeMillis();
        List list = s.get();
        for (int i = 0; i < total; i++) {
            list.add(0, number);
        }
        long end = System.currentTimeMillis();
        System.out.printf("在%s 最前面插入%d条数据,总共耗时 %d 毫秒 %n", type, total, end - start);
    }

}

原文地址:https://www.cnblogs.com/jeddzd/p/12336192.html

时间: 2024-10-31 02:22:10

Java自学-Lambda 方法引用的相关文章

java8 lambda方法引用

注意引用方法的参数列表与返回值类型要与函数式接口中的抽象方法的参数列表与返回值类型保持一致 主要有三种语法格式: * * 对象::实例方法名 * * 类::静态方法名 * * 类::实例方法名 public class Test05 { public static void main(String[] args) { // TODO Auto-generated method stub //注意引用方法的参数列表与返回值类型要与函数式接口中的抽象方法的参数列表与返回值类型保持一致 //lambd

Java 8Lambda之方法引用(Method References)

方法引用分为4类,方法引用也受到访问控制权限的限制,可以通过在引用位置是否能够调用被引用方法来判断.具体分类信息如下: 类型 使用方式 静态方法 ContainingClass::staticMethodName 指定实例的方法 containingObject::instanceMethodName 特定类实例的任意方法 ContainingType::methodName 构造方法 ClassName::new 引用静态方法 ContainingClass::staticMethodName

java中的方法引用

引用静态方法:类名称::static 方法名称: 引用某个对象的方法:对象::普通方法: 引用特定类方法:特定类::方法 引用构造方法:类名称::new 范例:引用静态方法 package com.java.demo; interface IMessage<P,R>{ // P表示方法的参数类型,R表示方法的返回值类型 public R change(P p); } public class TestDemo{ public static void main(String args[]){ /

Java学习笔记-方法引用

方法引用(Method Reference) 上一篇中记录了Lambda表达式,其可以创建匿名方法.当Lambda表达式只是调用一个存在的方法时,可以采用方法引用(JDK8具有的特性).如下: 1 public class Person { 2 3 public enum Sex { 4 MALE, FEMALE 5 } 6 7 String name; 8 LocalDate birthday; 9 Sex gender; 10 String emailAddress; 11 int age;

Java自学-面向对象 方法

Java类的方法 在LOL中,一个英雄可以做很多事情,比如超神,超鬼,坑队友 能做什么在类里面就叫做方法 示例 1 : 什么是方法 比如队友残血正在逃跑,你过去把路给别人挡住了,导致他被杀掉. 这就是坑队友 每个英雄....都可以坑 所以为Hero这个类,设计一个方法: keng public class Hero { String name; //姓名 float hp; //血量 float armor; //护甲 int moveSpeed; //移动速度 //坑队友 void keng(

JAVA 8 方法引用 - Method References

什么是方法引用 简单地说,就是一个Lambda表达式.在Java 8中,我们会使用Lambda表达式创建匿名方法,但是有时候,我们的Lambda表达式可能仅仅调用一个已存在的方法,而不做任何其它事,对于这种情况,通过一个方法名字来引用这个已存在的方法会更加清晰,Java 8的方法引用允许我们这样做.方法引用是一个更加紧凑,易读的Lambda表达式,注意方法引用是一个Lambda表达式,其中方法引用的操作符是双冒号"::". 方法引用例子 先看一个例子 首先定义一个Person类,如下:

009-jdk1.8版本新特性一-展方法,Lambda表达式,函数式接口、方法引用构造引用

一.JDK1.8 名称:Spider(蜘蛛) 发布日期:2014-03-18 新特性: 1.1.扩展方法[接口的默认方法] Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法. 在Java中只有单继承,如果要让一个类赋予新的特性,通常是使用接口来实现,在C++中支持多继承,允许一个子类同时具有多个父类的接口与功能,在其他语言中,让一个类同时具有其他的可复用代码的方法叫做mixin.新的Java 8 的这个特新在编译器实现的角度上来说更

Java 8新特性-4 方法引用

对于引用来说我们一般都是用在对象,而对象引用的特点是:不同的引用对象可以操作同一块内容! Java 8的方法引用定义了四种格式: 引用静态方法     ClassName :: staticMethodName 引用对象方法:  Object:: methodName 引用特定类型方法: ClassName :: methodName 引用构造方法: ClassName  :: new 静态方法引用示例 /** * 静态方法引用 * @param <P> 引用方法的参数类型 * @param

Java 8 lambda表达式示例

例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runnable实现方法,需要4行代码,而使用lambda表达式只需要一行代码.我们在这里做了什么呢?那就是用() -> {}代码块替代了整个匿名类. 1 // Java 8之前: 2 new Thread(new Runnable() { 3 @Override 4 public void run() {