【Java函数式编程】Lambda表达式,A算子,T算子

此合集仅仅当作字典查阅,字数很少,内容很多

为了能够读懂公司里的代码,为了能够早日进大厂,为了能够提高编程水平成为一流的程序员,为了能够实现梦想,函数式编程的学习必不可缺!!!


目录

FP优点

Lambda表达式

Lambda表达式的直观感受

Lambda表达式结构

Lambda表达式省略规则

创建流

单列集合创建流(Collection集合均为单列集合)

ArrayList

        LinkedList

Vector

HashSet

双列集合创建流(Map均为双列集合)        

HashMap

TreeMap

LinkedHashMap

数组创建流两种方式        

T算子

map

distinct

sorted

不带参

带参

flatmap

分流效果图

main函数部分

Author类部分

A算子

foreach

count

min/max


函数式编程:之后简称FP

FP优点

1.在处理大数据量式效率更高,但小数据量并不是

2.并行,并发编程,线性安全,原子性

3.代码可读性更高

4.消灭嵌套地狱

Lambda表达式

Lambda表达式的直观感受

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是一个线程");
            }
        }).start();

        //TODO  优化代码过后

        new Thread(()->{
            System.out.println("我是优化后的线程");
        }).start();

Lambda表达式结构

( XXX -> {

        XXX

})

Lambda表达式省略规则

1.参数类型可以省略

2.方法体只有一句代码时大括号、return和唯一一句代码的分号可以省略

3.方法只有一个参数时小括号可以省略

4.以上规则用中记,记中用

创建流

单列集合创建流(Collection集合均为单列集合)

ArrayList

        ArrayList<Integer> integerArrayList = new ArrayList<>();
        integerArrayList.add(1);
        integerArrayList.stream().forEach(System.out::println);

        
LinkedList

        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.add(1);
        linkedList.stream().forEach(System.out::println);



Vector

        Vector<Integer> vector = new Vector<>();
        vector.add(1);
        vector.stream().forEach(System.out::println);

HashSet

        HashSet<Integer> hashSet = new HashSet<>();
        hashSet.add(1);
        hashSet.stream().forEach(System.out::println);





 

双列集合创建流(Map均为双列集合)
        


HashMap

        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.entrySet()
                .stream()
                .forEach((entry) -> {});

TreeMap

        TreeMap<Object, Object> objectObjectTreeMap = new TreeMap<>();
        objectObjectTreeMap.entrySet()
                .stream()
                .forEach((entry) -> {});

LinkedHashMap

        LinkedHashMap<Object, Object> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.entrySet()
                .stream()
                .forEach((entry) -> {});

        

数组创建流两种方式
        

        int[] arr = {1,2,3,4,5};
        IntStream stream = Arrays.stream(arr);
        Stream<int[]> arr1 = Stream.of(arr);

        

T算子

map

一对一输出

        List<Author> sampleAuthors = AuthorFactory.createSampleAuthors();
        sampleAuthors.stream()
                .map(author -> author)
                .forEach(System.out::println);

distinct

消除重复的流数据,底层是Object的equals方法(重写hashCode和equals)

重写部分代码
 

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Author)) return false;
        Author author = (Author) o;
        return age == author.age && name.equals(author.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }

业务代码

        List<Author> sampleAuthors = AuthorFactory.createSampleAuthors();
        sampleAuthors.stream()
                .map(author -> author)
                .distinct()
                .forEach(System.out::println);

sorted

作用:调整顺序大小,按照你设定的规则按照从“大(小)”到“小(大)”输出

不带参

        
需要实现Comparator接口并重写compareTo方法,排名先后顺序自己试

        List<Author> sampleAuthors = AuthorFactory.createSampleAuthors();
        sampleAuthors.stream()
                .sorted()
                .forEach(System.out::println);

带参

        

new一个匿名内部类重写方法或者用Lambda表达式
 

        sampleAuthors.stream()
                .sorted(new Comparator<Author>() {
                    @Override
                    public int compare(Author o1, Author o2) {
                        return 0;
                    }
                })
                .forEach(System.out::println);
                sampleAuthors.stream()
                .sorted((o1, o2) -> 0)
                .forEach(System.out::println);

flatmap

作用:能够实现一对多,能够将一条流分散成多条流

作用在spark合集中已经提到过,这里自己写了一个作者类,然后执行flatmap转换算子以实现"一个流指向多个流的操作"

分流效果图

main函数部分
//创建书籍列表以及各个作者
        List<String> list = Arrays.asList("Java", "Python", "C++", "JavaScript", "C#", "PHP");
        ArrayList booklist1 = new ArrayList<>(list);
        ArrayList booklist2 = new ArrayList<>(list);
        ArrayList booklist3 = new ArrayList<>(list);
        ArrayList booklist4 = new ArrayList<>(list);

        Author author1 = new Author(10, "张三", new Author.BookList(booklist1));
        Author author2 = new Author(10, "李四", new Author.BookList(booklist2));
        Author author3 = new Author(10, "王五", new Author.BookList(booklist3));
        Author author4 = new Author(10, "麻六", new Author.BookList(booklist4));


        //创建流
        List<Author> authorList = Arrays.asList(author1, author2, author3, author4);
        authorList.stream()
                .flatMap(Author::getBooks)
                .forEach(System.out::println);
Author类部分
class Author implements Comparable<Author> {

    private int age;
    private String name;
    private BookList booklist;

    public Author(int age, String name, BookList booklist) {
        this.age = age;
        this.name = name;
        this.booklist = booklist;
    }

    static class BookList {
        private List<String> name;

        public BookList(List<String> name) {
            this.name = name;
        }

        public List<String> getName() {
            return name;
        }
    }

    public Stream<String> getBooks() {
        return booklist.getName().stream();
    }

    @Override
    public String toString() {
        return "Author{" +
                "age=" + age +
                ", name='" + name + '\'' + ", booklist=" + booklist +
                '}';
    }

    @Override
    public int compareTo(Author o) {
        return o.age - this.age;//除了考试和面试会提到之外,记忆这个东西没有意义
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (!(obj instanceof Author)) return false;
        Author a = (Author) obj;
        return a.age == this.age && a.name.equals(this.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }
}

 

A算子

foreach

作用:输出、输出、还是TM的输出!!!

其中传入Consumer消费者接口实现其中的accept方法

        List<Author> sampleAuthors = AuthorFactory.createSampleAuthors();
        sampleAuthors.stream()
                .forEach(new Consumer<Author>() {
                    @Override
                    public void accept(Author author) {
                        System.out.println(author);
                    }
                });

Lambda表达式形式(方法引用)

        List<Author> sampleAuthors = AuthorFactory.createSampleAuthors();
        sampleAuthors.stream()
                .forEach(System.out::println);

count

获得当前流中元素的个数

        List<Author> sampleAuthors = AuthorFactory.createSampleAuthors();
        long count = sampleAuthors.stream()
                .count();
        System.out.println(count);

min/max

取得流中的最大/最小值
        

        List<Author> sampleAuthors = AuthorFactory.createSampleAuthors();
        sampleAuthors.stream()
                .max((o1, o2) -> o1.getAge() - o2.getAge())
                .ifPresent(System.out::println);
        List<Author> sampleAuthors = AuthorFactory.createSampleAuthors();
        sampleAuthors.stream()
                .min((o1, o2) -> o1.getAge() - o2.getAge())
                .ifPresent(System.out::println);

其中ifPresent方法用来防止空值,避免空指针异常。

<think> 嗯,用户这次问的是函数式程序设计中"mul"的含义,结合之前的引用来看,用户似乎对编程中函数的不同应用场景很感兴趣。之前引用里提到过Python的闭包特性、Java的静态方法,这些其实都和函数式编程有微妙关联。 用户可能正在学习函数式编程的基础概念,需要明确区分传统命令式编程中的函数。注意到用户特意标注"函数式程序设计"这个限定范围,说明ta已经意识到不同范式下术语的差异。不过用户引用的资料都是面向对象或命令式语言的例子,可能需要更针对性的解释。 "mul"在函数式语境下通常指代纯函数式的乘法操作,具有三个关键特征:引用透明性(结果只依赖输入参数)、无副作用(不修改外部状态)、可作为高阶函数的参数。这和用户引用[3]里Java的静态方法Mul有本质区别——后者虽然也是乘法,但属于面向对象中的工具方法。 考虑到用户引用了Python闭包特性的例子,正好可以用闭包实现函数式mul:比如(lambda x: lambda y: x*y)就是一个柯里化的mul函数。这个例子还能自然衔接用户提到的late binding问题——如果用命令式思维写闭包mul容易掉进变量绑定的坑,但纯函数式写法就能避免。 用户似乎容易混淆不同编程范式下的相似术语,回复时需要强调"函数"在数学、命令式编程函数式编程三重语境下的区别。比如数学函数关注映射关系,命令式函数强调过程封装,而函数式中的"函数"本质是数学函数在程序中的实现。 </think> 在函数式程序设计中,**`mul`** 是 **乘法(multiplication)操作的函数化抽象**,其核心含义是:**将乘法运算封装为纯函数**,强调无副作用和引用透明的特性。以下是关键解析: --- ### 1. **函数式编程中 `mul` 的本质** - **纯函数实现**: `mul` 接收输入参数(通常为两个数值),返回其乘积,且不依赖或修改外部状态。 示例(Haskell): ```haskell mul :: Num a => a -> a -> a mul x y = x * y ``` 调用 `mul 3 5` 始终返回 `15`,不受上下文影响 [^1]。 - **柯里化(Currying)支持**: 函数式语言中,`mul` 可部分应用(partial application),生成新函数: ```haskell double = mul 2 -- 创建新函数:double x = 2 * x double 8 -- 返回 16 ``` --- ### 2. **与传统编程的差异** - **对比面向对象方法**(引用[3]示例): 面向对象中的 `Mul` 是类的静态方法,需通过类调用(如 `MyMath.Mul(3,5)`)。 函数式 `mul` 是独立的一等公民(first-class function),可直接传递或组合: ```python # Python 函数式示例 from operator import mul list(map(mul, [1,2,3], [4,5,6])) # 输出 [4, 10, 18] ``` - **副作用隔离**: 函数式 `mul` 无隐式状态修改(如不修改全局变量),避免引用[2]中闭包误用导致的意外行为。 --- ### 3. **在函数式组合中的应用** - **管道化处理**: `mul` 可与其他函数组合成处理链: ```javascript // JavaScript 示例 (Ramda库) const pipeline = R.pipe( R.map(x => x + 1), // 所有元素加1 R.reduce(mul, 1) // 计算乘积 ); pipeline([2, 3, 4]); // (3*4*5)=60 ``` - **代数结构的体现**: 在抽象代数中,`mul` 可能对应群(Group)、环(Ring)等数学结构的二元运算,强化代码的数学可推导性。 --- ### 4. **设计意义** - **语义明确性**: `mul` 作为命名清晰的原子函数,提升代码可读性(优于直接使用 `*` 运算符的嵌套表达式)。 - **高阶函数基础**: 作为基础算子,支撑 `map/reduce/filter` 等操作(如 `reduce(mul, list)` 计算列表乘积)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值