为了账号安全,请及时绑定邮箱和手机立即绑定

【备战春招】第18天 Java高级编程(Lambda表达式)

标签:
Java 算法
课程名称:Java工程师2022版
课程章节:Java高级编程
课程讲师:IT老齐 悟空 八戒猪 神思者 Leo
课程内容:Lambda表达式

一、反射的实际应用
1.Field成员变量类
Field对应某个具体类中的成员变量的声明。
Field对象使用classObj.getField()方法获取。
通过Field对象可为某种对象成员变量赋值/取值。

方法 用途
classObj.getField() 获取指定public修饰的成员变量对象
fieldObj.set() 为某种对象指定成员变量赋值
fieldObj.get() 获取某对象指定成员变量数值

成员变量在java中也叫类的属性,也叫字段,都是一个东西。
2.getDeclared系列方法
getDeclaredConstructor(s)|Method(s)|Field(s)获取对应对象。
getConstructor(s)|Method(s)|Field(s)只能获取public对象。
访问非作用域内构造方法、方法、成员变量,会抛出异常。
3.反射的实际应用
只有当程序启动的时候,程序才知道去实例化哪个类,这也就是反射最大的优势。
首先创建I18n的接口

package com.imooc.i18n;
public interface I18n {
    public String say();
}

准备三种不同语言将要输出的文件。
第一种俄语。

package com.imooc.i18n;
public class Zhcn implements I18n{
    @Override
    public String say() {
        return "Жизнь - это постоянная борьба.";
    }
}

第二种中文。

package com.imooc.i18n;
public class Zhcn implements I18n{
    @Override
    public String say() {
        return "生命不息奋斗不止";
    }
}

第三种是英语。

package com.imooc.i18n;
public class En implements I18n{
    @Override
    public String say() {
        return "Cease to the Struggle and cease to the life";
    }
}

然后就是书写配置文件。

language = com.imooc.i18n.Ru

每次需要变化内容的时候,就只需要改变最后的Ru就可以切换到不同语言的内容了。
最后书写函数主入口类。

package com.imooc.i18n;
import java.io.FileInputStream;
import java.net.URLDecoder;
import java.util.Properties;
public class Application {
    public static void say(){
        Properties properties = new Properties();
        String configPath = Application.class.getResource("/config.properties").getPath();
        try {
            configPath = URLDecoder.decode(configPath, "UTF-8");
            properties.load(new FileInputStream(configPath));
            String language = properties.getProperty("language");
            I18n i18n = (I18n)Class.forName(language).newInstance();
            System.out.println(i18n.say());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        Application.say();
    }
}

这里特别强调的是new URLDecoder().decode这种写法在15的时候就已经淘汰了,所以现在可以使用URLDecoder.decode去替代之前的写法。
二、Lambda表达式介绍
1.什么是Lambda表达式?
JDK8开始支持Lambda表达式,用来让程序编写更优雅。
利用Lambda可以更简洁的实现匿名内部类与函数声明与调用。
基于Lambda提供stream流式处理极大简化对集合的操作。
2.Lambda语法格式
整体的格式Lambda Operator(参数列表) -> 实现语句 使用逗号分隔参数,参数类型可以省略,单参数括号可省略。单行直接写,多行用{}包括。

package com.imooc.lambda;
public class LambdaSample {
    public static void main(String[] args) {
        //1.标准使用方式
        //约束条件:Lambda表达式只能实现有且只有一个抽象方法的接口,Java称为“函数式接口”
        MathOperation addition = (Integer a, Integer b) -> {
            System.out.println("加法运算");
            return a+b+0f;
        };
        System.out.println(addition.operate(5,3));
        //2.Lambda允许忽略参数类型
        MathOperation substraction = (a, b) -> {
            return a - b + 0f;
        };
        System.out.println(substraction.operate(5,3));
        //3.单行实现代码可以省略大括号和return
        MathOperation multiplication = (a, b) -> a*b+0f;
        System.out.println(multiplication.operate(5,3));
        //只有一个参数的情况下,小括号也可以省略
    }
}

Lambda表达式只能有一个抽象方法的接口,Java称为函数时接口,如果出现了两个或者大于两个的抽象方法,那么整个代码都会报错。
三、函数式编程
1.什么是函数式编程?
函数式编程是基于函数式接口并使用lambda表达的编程方法。
函数式编程理念是将代码作为可重用数据代入到程序运行中。
函数式编程强调“你想做什么”,而不是“你想怎么做”。
2.什么是函数式接口?
函数式接口是有且只有一个抽象方法的接口。
Java中拥有大量函数式接口,如java.lang.Runnable。
JDK8后提供了一些列新的函数式接口,位于java.util.function。
3.函数式接口Predicate
Predicate是新增的函数式接口,位于java.util.function。
Predicate用于测试传入的数据是否满足判断要求。
Predicate接口需要实现test()方法进行逻辑判断。
注意Predicate最主要的一个点还是运行时,极大的扩展了灵活性。
4.Consumer接口

接口 用途
Consumer 对应有一个输入参数无输出的功能代码
Function 对应有一个输入参数且需要返回数据的功能代码
Predicate 用于条件判断,固定返回布尔值

在自己书写函数式接口的时候,可以写一个注解,@FunctionalInterface 通知编译器这是函数式接口,进行抽象方法检查。
函数式编程与面向对象编程比较。

面向对象编程 函数式编程
设计思路 面向对象 面向过程
开发侧重 侧重过程,重分析,重设计 侧重结果,快速实现
可读性 结构复杂,相对较差 更适合人眼阅读,可读性更好
代码量
开发问题 设计不当,就会出现线程安全问题 不会出现线程安全问题
健壮性
使用场景 中大型大型项目,多人协作工程 小型应用,要求快速实现

四、Stream流
1.Stream流介绍
Stream流式处理是建立在Lambda基础上的多数据处理技术。
Stream对集合数据处理进行高度抽象,极大简化代码量。
Stream可对集合进行迭代,去重,筛选,排序,聚合等一系列处理。
Stream常用方法

接口 用途
forEach 循环遍历
map map方法用于映射每一个元素到对应的结果
filter filter方法用于通过设置的条件过滤出元素
limit limit方法用于获取指定数量的流
sorted sorted方法用于对流进行排序
Collectors Collectors类实现将流转换成集合和聚合元素

2.创建流的五种方式

package com.imooc.stream;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
 * Stream流对象的五种创建方式
 */
public class StreamGenerator {
    //1.基于数组进行创建
    @Test
    public void generator1(){
        String[] arr = {"Lily", "Andy", "Jackson", "Smith"};
        Stream<String> stream = Stream.of(arr);
        stream.forEach(s -> System.out.println(s));
    }
    //2.基于集合进行创建
    @Test
    public void generator2(){
        List<String> list = new ArrayList<>();
        list.add("Lily");
        list.add("Andy");
        list.add("Jackson");
        list.add("Smith");
        Stream<String> stream = list.stream();
        stream.forEach(s -> System.out.println(s));
    }
    //3.利用generator方法创建无限长度流
    @Test
    public void generator3(){
        Stream<Integer> stream = Stream.generate(() -> new Random().nextInt(100000));
        stream.limit(10).forEach(i -> System.out.println(i));
    }
    //4.基于迭代器创建流
    @Test
    public void generator4(){
        Stream<Integer> stream = Stream.iterate(1,n->n+1);
        stream.limit(100).forEach(i -> System.out.println(i));
    }
    //5.基于字符序列创建流
    @Test
    public void generator5(){
        String str = "abcdefg我的";
        IntStream stream = str.chars();
        stream.forEach(c -> System.out.println((char) c));
    }
}

3.stream常用方法
提取集合中所有偶数并求和。

package com.imooc.stream;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class StreamMethod {
    //提取集合中所有偶数并求和
    @Test
    public void case1(){
        List<String> list = Arrays.asList("1","2","3","4","5","6");
        int sum = list.stream() //获取stream对象
            .mapToInt(s -> Integer.parseInt(s)) //mapToInt将流中每一个数据转为整数
            .filter(n -> n%2==0)  //filter对流中的数据进行过滤
            .sum();  //求和
        System.out.println(sum);
    }
}

所有名字首字母大写。

    public void case2(){
        List<String> list = Arrays.asList("lily","smith","jackson");
        List newList = list.stream()
                .map(s -> s.substring(0,1).toUpperCase() + s.substring(1))
                //.forEach(s -> System.out.println(s));
                .collect(Collectors.toList());
        System.out.println(newList);
    }

将所有奇数从大到小继续宁排序,且不许出现重复。

    public void case3(){
        List<Integer> list = Arrays.asList(1,60,38,21,51,60,51,73);
        List newList = list.stream().distinct()  //去除重复的流数据
                .filter(n -> n%2==1)
                .sorted((a,b) -> a-b)  //流数据排序,a-b是升序,b-a是降序
                .collect(Collectors.toList());
        System.out.println(newList);
    }
课程总结:

1.反射的实际应用。
2.Lambda表达式介绍。
3.函数式编程。
4.Stream流。
图片描述

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消