1 Star 1 Fork 0

Justin/lambdaLearnDemo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

lambdaLearnDemo

介绍

lambda表达式练习

lambda表达式是表达接口函数的实现

函数式接口只能有一个抽象方法,可包含多个static方法

lambda表达式

val -> System.out.println(val);

->左边为参数,右边为函数体

不使用lambda来实现接口的打印

package com.justin.java8;

/**
 * @author jgn
 */
public class LambdaDemo1 {
    
    interface Printer{
        void printer(String val);
    }

    public void printSomething(String something ,Printer printer){
        printer.printer(something);
    }

    public static void main(String[] args) {
        LambdaDemo1 lambdaDemo1 = new LambdaDemo1();
        String some = "Justin";
           // 无lambda实现
           /* Printer printer = new Printer() {
                public void printer(String val) {
                    System.out.println(val);
                }
            };*/
                
           // 使用lambda实现
           Printer printer = (String val) ->{
               System.out.println(val);
           };
        lambdaDemo1.printSomething(some,printer);
    }
}

lambda表达式的简化

 Printer printer = (String val) ->{
    System.out.println(val);
};
lambdaDemo1.prinSomething(some,printer);

去参数的对象类型

Printer printer = (val) ->{
    System.out.println(val);
};
lambdaDemo1.printSomething(some,printer);

去参数的小括号

Printer printer = val ->{
    System.out.println(val);
};
lambdaDemo1.printSomething(some,printer);

要执行的语句只有一句的话可以去大括号变成一句

Printer printer = val -> System.out.println(val);
lambdaDemo1.printSomething(some,printer);

可代替对象放入放入方法的参数里

lambdaDemo1.printSomething(some,val -> System.out.println(val));

当实现的接口没有任何参数时

interface Printer{
        void printer();
    }

() -> System.out.println("")

如果为控制台打印使用特有的lambda表达式进行书写

lambdaDemo1.printSomething(some, System.out::println);

小结

  • 箭头左侧没有指定参数类型,编译器会从接口方法的形参中推断其类型
  • 只有一个参数时,可省略参数的括号
  • 函数体只有一行可以省略花括号(大括号)

Java Stream的转换

/**
 * stream 流式处理
 * @author jgn
 */
public class StreamDemo1 {

    public static void main(String[] args) {
        List<String> cars = Arrays.asList("aodi", "dazhong", "beichi", "suv");
        List<String> sorted = cars.stream()// list转流
                .filter(s -> s.startsWith("d"))// 过滤
                .map(String::toUpperCase)// 映射 大写处理
                .sorted()// 排序
                .collect(Collectors.toList());// 流转回list

        System.out.println(sorted);
        // 数组转流
        String[] array = {"system","out","sorted"};
        Stream<String> names = Stream.of(array);
    
        // 集合类转流
        List<String> namelist = Arrays.asList("map", "set", "stack");
        Stream<String> stream = namelist.stream();
    
        // 文件转流
        Stream<String> lines = Files.lines(Paths.get("file.txt"));
    }
  
}

谓词逻辑与谓词

 /**
 * Returns a stream consisting of the elements of this stream that match
 * the given predicate.
 *
 * <p>This is an <a href="package-summary.html#StreamOps">intermediate
 * operation</a>.
 *
 * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
 *                  <a href="package-summary.html#Statelessness">stateless</a>
 *                  predicate to apply to each element to determine if it
 *                  should be included
 * @return the new stream
 */
Stream<T> filter(Predicate<? super T> predicate);

predicate 是谓语/断言的意思

谓词逻辑和语言学所讲的「谓词」是相同的,都是“表达客体性质或关系的词项”。不过,谓词逻辑的谓词范围要小于语言学的谓词范围,因为谓词逻辑只是语言学逻辑的一个子集,除此之外,还有模态逻辑,情态逻辑,句链逻辑,内涵逻辑等

谓词:用来代替或者展示其客体性质、特征或者客体之间关系的词项

举个例子sql语句中的where and 就是一个谓词逻辑,

谓词逻辑的复用

通常情况下,filter函数中的lambda表达式就是一次性使用的谓词逻辑。

如果谓词逻辑要在多处使用,通常将它抽取出来单独定义到它所限定的主语实体中

/**
 * 实体类
 */
@Data
@AllArgsConstructor
public class Employee {

    private Integer id;
    private Integer age;   //年龄
    private String gender;  //性别
    private String firstName;
    private String lastName;

    // 谓语逻辑
    
    /**
     * 年纪大于70的
     */
    public static Predicate<Employee> ageGreaterThan70 =  x -> x.getAge() >70;

    /**
     * 性别是男的
     */
    public static Predicate<Employee> genderM = x -> x.getGender().equals("M");

}

复用测试

public class StreamFilterPredicate {

    public static void main(String[] args) {
        Employee e1 = new Employee(1,23,"M","Rick","Beethovan");
        Employee e2 = new Employee(2,13,"F","Martina","Hengis");
        Employee e3 = new Employee(3,43,"M","Ricky","Martin");
        Employee e4 = new Employee(4,26,"M","Jon","Lowman");
        Employee e5 = new Employee(5,19,"F","Cristine","Maria");
        Employee e6 = new Employee(6,15,"M","David","Feezor");
        Employee e7 = new Employee(7,68,"F","Melissa","Roy");
        Employee e8 = new Employee(8,79,"M","Alex","Gussin");
        Employee e9 = new Employee(9,15,"F","Neetu","Singh");
        Employee e10 = new Employee(10,45,"M","Naveen","Jain");

        List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
        // 过滤年龄大于70且为男性的员工 ,一次性的谓语逻辑
        List<Employee> employeesList = employees.stream()
                .filter(e -> e.getAge() > 70 && e.getGender().equals("M"))
                .collect(Collectors.toList());
        // 逻辑断言的复用
        // and
        List<Employee> employeesListAnd = employees.stream()
                .filter(Employee.ageGreaterThan70.and(Employee.genderM)).collect(Collectors.toList());
        // or
        List<Employee> employeesListOr = employees.stream()
                .filter(Employee.ageGreaterThan70.or(Employee.genderM)).collect(Collectors.toList());
        // negate 取反
        List<Employee> employeesListNegate = employees.stream()
                .filter(Employee.ageGreaterThan70.or(Employee.genderM).negate()).collect(Collectors.toList());
        
        System.out.println(employeesList);
        System.out.println(employeesListAnd);
        System.out.println(employeesListOr);
        System.out.println(employeesListNegate);
    }
}

map 的数据转换

map进行数据格式状态的转换,和类型的转换,

map flatmap 都是无状态的操作

只进行一步操作

List<String> alpha = Arrays.asList("Monkey","Lion","Giraffe","Lemur");

// 不使用管道流,将字母都转为大写
List<String> alphaUpper = new ArrayList<>();
for (String s : alpha) {
    alphaUpper.add(s.toUpperCase());
}
System.out.println("不用管道流:"+alphaUpper);

List<String> collect = alpha.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println("用管道流:"+collect);

List<Integer> lengths = alpha.stream().map(String::length).collect(Collectors.toList());
System.out.println("获取每个元素的长度:"+lengths);

List<String> collect1 = collect.stream().map(String::toLowerCase).collect(Collectors.toList());
System.out.println(collect1);
// 字符串数组
Stream.of("Monkey","Lion","Giraffe","Lemur").mapToInt(String::length).forEach(System.out::println);

实现复杂的流式映射,使用map或peek

map与peek的区别

  • map要返回值
  • peek不需要
     List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);

        // 年龄+1,M变为male F变为female
//        List<Employee> collect = employees.stream().map(x -> {
//            x.setAge(x.getAge() + 1);
//            x.setGender(x.getGender().equals("M") ? "male" : "female");
//            return x;
//        }).collect(Collectors.toList());

        List<Employee> collect = employees.stream().peek(x -> {
            x.setAge(x.getAge() + 1);
            x.setGender(x.getGender().equals("M") ? "male" : "female");
        }).collect(Collectors.toList());

        System.out.println(collect);

faltMap

faltMap 就是将多个分开的管道数据展开到一个管道

List<String> words = Arrays.asList("hello","word","justin");
words.stream().map(w -> Arrays.stream(w.split(""))).forEach(System.out::println);
// java.util.stream.ReferencePipeline$Head@7699a589
// java.util.stream.ReferencePipeline$Head@58372a00
// java.util.stream.ReferencePipeline$Head@4dd8dc3
words.stream().flatMap(w ->Arrays.stream(w.split(""))).forEach(System.out::println);
    

有状态和无状态

状态通常代表操作的公共的数据,需要进行额外的存储,比如存在redis或内存,通常会被多人、多用户多线程多次操作会涉及到状态的管理

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

语言

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/justin98/lambda-learn-demo.git
git@gitee.com:justin98/lambda-learn-demo.git
justin98
lambda-learn-demo
lambdaLearnDemo
master

搜索帮助