Java 复习笔记 - Lambda 表达式 he 经典算法题

文章目录

  • Lambda表达式 概述
    • (一)基本作用
    • (二)特点
  • 一,初识Java中的Lambda 表达式
  • 二,函数式编程
  • 三,省略写法
  • 四,练习:使用Lambda 表达式 简化Comparator接口的匿名形式
  • 综合练习
  • 一,按照需求进行排序
  • 二,不死神兔
  • 三,猴子吃桃
  • 四,爬楼梯


Lambda表达式 概述

Lambda 表达式(Lambda Expressions)是一种简洁的表示匿名函数(anonymous function)的方法,它允许将函数作为方法的参数(MOP,Method Ordered Parameters)或者代码中的一部分进行传递。这种表达式在 Python、JavaScript、Java 等多种编程语言中都有应用。

(一)基本作用

Lambda表达式在Java和其他函数式编程语言中有着广泛的应用。其主要作用包括:

  1. 简化代码:Lambda表达式可以作为参数传递给其他函数,或者在函数中创建简短、可读性更高的代码,这样可以帮助减少代码量,并提升代码的可读性和可维护性。
  2. 函数式编程:Lambda表达式使得函数式编程在Java中变得可能。函数式编程强调将计算作为数学上的函数求值,避免改变状态和使用可变数据。通过Lambda表达式,可以更方便地实现函数式接口。
  3. 匿名函数:Lambda表达式是一种匿名函数,可以作为参数传递给其他函数,或者在函数中作为代码片段直接使用,而不需要定义一个显式的函数名称。
  4. 提升代码可维护性:由于Lambda表达式可以使代码更加简洁和模块化,这使得代码更容易理解和维护。

总的来说,Lambda表达式是一种强大的工具,可以使代码更简洁,更易读,更模块化,从而提升代码的可维护性和可重用性。

(二)特点

Lambda表达式是Java 8中最重要的新功能之一,它有以下几个特点:

  1. 函数式编程:Lambda表达式可以替代只有一个抽象函数的接口实现,它是一种函数式编程的方式,可以帮助我们编写更简洁易懂的代码。
  2. 参数类型自动推断:Lambda表达式中的参数类型可以自动推断,不需要显式地指定类型。
  3. 代码量少、简洁:使用Lambda表达式可以将代码量减少,使代码更加简洁易懂。Lambda表达式的语法也很简洁,易于编写和阅读。

Lambda表达式的应用场景非常广泛,它可以应用于任何有函数式接口的地方,例如集合、框架的迭代、遍历、过滤数据的操作等。

一,初识Java中的Lambda 表达式

下面是一个简单的Java Lambda表达式的示例,它使用Lambda表达式来实现一个简单的接口方法:

interface MyInterface {void doSomething();
}public class LambdaExample {public static void main(String[] args) {// 使用Lambda表达式实现MyInterface接口的doSomething方法MyInterface myLambda = () -> System.out.println("Hello Lambda!");// 调用MyInterface接口的doSomething方法myLambda.doSomething();}
}

输出:

Hello Lambda!

在这个示例中,定义了一个MyInterface接口,它只有一个没有参数的doSomething方法。然后在main方法中使用Lambda表达式来创建一个实现该接口的对象,并将其赋值给myLambda变量。最后,调用myLambda对象的doSomething方法,该方法会输出“Hello Lambda!”。

二,函数式编程

函数式编程是一种编程范式,它将计算视为数学上的函数求值,并避免改变状态和使用可变数据。在 Java 中,函数式编程的主要特点包括:

  1. 不可变性(Immutability): 在函数式编程中,一旦一个变量被赋值,你就不能改变它。这意味着你不能更改变量的状态,这也被称为“不可变性”。
  2. 纯函数(Pure Functions): 纯函数是一种既不改变外部状态也不依赖外部状态的函数,它给定相同的输入就会产生相同的输出,而且没有任何副作用。
  3. 高阶函数(Higher-Order Functions): 高阶函数是接受一个或多个函数作为输入(参数)或返回一个函数作为结果的函数。

Java 8 引入了 Lambda 表达式和函数式接口,使得 Java 编程语言更加支持函数式编程。以下是一些 Java 8 之后的函数式编程例子:

Lambda 表达式

Lambda 表达式是一种简洁的表示匿名函数的方法,它没有名称,但有参数列表,函数主体,返回类型,并且可以被赋值给变量或传递给方法作为参数。

例如:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);// 使用 lambda 表达式实现过滤功能
List<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());

在这个例子中,n -> n % 2 == 0 就是一个 Lambda 表达式,它实现了 Filter<Integer> 接口的 test 方法。

函数式接口

函数式接口是只有一个抽象方法的接口。Java 8 中的 FunctionalInterface 注解可以标记这样的接口。

例如:

@FunctionalInterface
interface GreetingService {void sayMessage(String message);
}

然后,你可以使用 Lambda 表达式或方法引用实现这个接口:

GreetingService greetService1 = message -> System.out.println("Hello " + message);
GreetingService greetService2 = System.out::println;

greetService1greetService2都实现了GreetingService接口的sayMessage` 方法。

三,省略写法

Lambda表达式可以省略一些元素以使代码更简洁,以下是Lambda表达式的一些省略写法:

  1. 参数类型可以省略不写。如果只有一个参数,参数类型可以省略,同时()也可以省略。
  2. 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写,同时要省略分号。
  3. 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写。此时,如果这行代码是return语句,必须省略return不写,同时也必须省略";"。

以上就是Lambda表达式的一些省略写法,这些规则的使用可以使你的代码看起来更加简洁易读。

下面展示一个Java Lambda表达式的省略写法示例:

List<String> list = Arrays.asList("Apple", "Banana", "Orange");// 原始Lambda表达式
list.stream().filter(s -> s.startsWith("A")).forEach(System.out::println);// 省略参数类型的Lambda表达式
list.stream().filter(s -> s.startsWith("A")).forEach(System.out::println);// 省略大括号和分号的Lambda表达式
list.stream().filter(s -> s.startsWith("A")).forEach(s -> System.out.println(s));// 省略return语句的Lambda表达式
list.stream().filter(s -> s.startsWith("A")).forEach(s -> System.out.println(s));

这个示例中,创建了一个字符串列表,并使用Lambda表达式对列表进行过滤和输出。在第一个Lambda表达式中,没有省略任何内容。在第二个Lambda表达式中,省略了参数类型。在第三个Lambda表达式中,省略了大括号和分号。在第四个Lambda表达式中,省略了return语句。

四,练习:使用Lambda 表达式 简化Comparator接口的匿名形式

需求:定义数组并存储一些字符串,利用Arrays中的sort方法进行排序,按照字符串的长度进行排序,短的在前面,长的在后面(暂时不比较字符串里面的内容)。

在Java中,可以使用Lambda表达式和Comparator接口来简化排序操作。以下是按照字符串长度进行排序的示例:

import java.util.Arrays;
import java.util.Comparator;public class Main {public static void main(String[] args) {// 定义并初始化字符串数组String[] strings = {"Java", "Python", "C", "JavaScript", "Go"};// 使用Lambda表达式和Comparator接口进行排序Arrays.sort(strings, Comparator.comparingInt(String::length));// 打印排序后的数组for (String str : strings) {System.out.println(str);}}
}

在这个示例中,Comparator.comparingInt(String::length)是一个Lambda表达式,它实现了Comparator接口的compare方法。这个表达式接受两个字符串参数,并通过调用String::length方法获取它们的长度,然后比较这两个长度值。

这个Lambda表达式相当于下面的匿名类实现:

Arrays.sort(strings, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return Integer.compare(s1.length(), s2.length());}
});

使用Lambda表达式可以简化代码,并提高代码的可读性。

综合练习

一,按照需求进行排序

需求:定义数组并存储一些朋友对象,利用Arrays中的sort方法进行排序。
属性有姓名、年龄和身高。
按照年龄的大小进行排序,年龄一样,按照升高排序,身高一样按照姓名的字母进行排序(姓名中不要有中文或特殊字符)。

在Java中,可以创建一个Friend类来存储朋友的姓名、年龄和身高,然后使用Arrays.sort()方法和Lambda表达式来排序。

首先,创建一个Friend类:

public class Friend {private String name;private int age;private double height;public Friend(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}public String getName() {return name;}public int getAge() {return age;}public double getHeight() {return height;}@Overridepublic String toString() {return "Friend{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';}
}

然后,你可以创建一个Friend数组并排序:

import java.util.Arrays;
import java.util.Comparator;public class Main {public static void main(String[] args) {Friend[] friends = new Friend[]{new Friend("Alice", 25, 160.5),new Friend("Bob", 20, 175.2),new Friend("Charlie", 23, 170.0),new Friend("David", 20, 172.0),new Friend("Eve", 25, 155.0)};Arrays.sort(friends, Comparator.comparingInt((Friend f) -> f.getAge()).thenComparingDouble(f -> f.getHeight()).thenComparing(f -> f.getName()));for (Friend friend : friends) {System.out.println(friend);}}
}

在这个例子中,Arrays.sort()方法使用一个自定义的比较器来排序。比较器首先比较年龄,如果年龄相同,则比较身高,如果身高也相同,则比较姓名。

二,不死神兔

需求:有个很有名的数学逻辑题叫做不死神兔问题,有一対兔子,从出生到第三个月起每个月都生一对兔子,小兔子长到第三个月后又生一对兔子,假设兔子都不死,问第十二个月的兔子对数为多少?

这是一个经典的斐波那契数列问题,下面是一个的Java示例,可以计算第十二个月的兔子对数:

public class RabbitProblem {public static void main(String[] args) {int months = 12;int[] rabbitPairs = new int[months];// 初始化前三个月的兔子对数rabbitPairs[0] = 1;rabbitPairs[1] = 1;rabbitPairs[2] = 1;// 计算后九个月的兔子对数for (int i = 3; i < months; i++) {rabbitPairs[i] = rabbitPairs[i - 1] + rabbitPairs[i - 2];}// 输出第十二个月的兔子对数System.out.println("第十二个月的兔子对数为:" + rabbitPairs[months - 1]);}
}

这段代码首先定义了一个长度为12的数组,用于存储每个月的兔子对数。然后,初始化前三个月的兔子对数,都是1对。接着,使用一个循环计算后九个月的兔子对数,每个月的兔子对数等于前两个月的兔子对数之和。最后,我们输出第十二个月的兔子对数。

三,猴子吃桃

需求:有一个猴子摘了一堆桃子,第一天吃了一半,嘴馋又多吃了一个,第二天吃剩余的一半,同样嘴馋多吃了一个,第三天亦然,第10天的时候(还没有吃),发现只剩下一个桃子了,问这个猴子摘了多少桃子?

这是一个经典的数学问题,可以用递归或者循环来解决。这里我们给出使用循环的Java代码。

public class MonkeyPeach {public static void main(String[] args) {int day = 10;int peach = 1; // 第10天有1个桃子for (int i = 1; i < day; i++) {// 每一天猴子都吃前一天剩下的一半再加一个peach = (peach + 1) * 2;}System.out.println("猴子摘了 " + peach + " 个桃子");}
}

四,爬楼梯

需求:帅气的小明喜欢爬楼梯,他有的时候一次爬一个台阶,有的时候一次爬两个台阶。如果这个楼梯有20个台阶,小明一个共有多少种爬法?

运行结果:
1层台阶 1种爬法
2层台阶 2种爬法
7层台阶 21种爬法

这个问题实际上是一个经典的动态规划问题,类似于斐波那契数列问题。小明爬楼梯的方式实际上就是斐波那契数列的表现形式,即F(n) = F(n-1) + F(n-2)

以下是一段Java代码,可以计算出小明爬20层楼梯有多少种爬法:

public class Main {public static void main(String[] args) {int n = 20;System.out.println(n + "层台阶 " + climbStairs(n) + "种爬法");}public static int climbStairs(int n) {if (n <= 2) {return n;}int[] dp = new int[n + 1];dp[1] = 1;dp[2] = 2;for (int i = 3; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
}

在这段代码中,climbStairs函数会计算出爬n层楼梯有多少种爬法。这个函数首先处理了小于等于2的情况,然后用动态规划的方式计算出了大于2的情况。动态规划的思路是,爬到第i层的方法数等于爬到第i-1层的方法数加上爬到第i-2层的方法数。最后,这个函数返回了爬到n层的方法数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/79035.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TSINGSEE青犀视频AI算法助力构建城市市容·街面秩序管理解决方案

随着城市化进程加快&#xff0c;未经合理规划设置自然形成的马路市场越来越多&#xff0c;这不仅存在交通安全隐患&#xff0c;也造成了市容秩序混乱&#xff0c;严重影响城市市容面貌。 TSINGSEE青犀AI智能分析网关V3内部部署了几十种算法&#xff0c;包括人脸、人体、车辆、…

学习笔记:卸载nav2 navigation2导航

nav2二进制文件安装 nav2导航安装方式分为二进制文件安装和源码方式安装&#xff0c;如果想用最快的方式跑通代码&#xff0c;推荐二进制安装&#xff0c;不用编译&#xff0c;没有缺少依赖编译失败的烦恼&#xff0c; 安装命令&#xff1a; sudo apt install ros-$ROS_DISTR…

iTOP-RK3568开发板Linux 修改kernel logo

本文档配套资料在网盘资料“iTOP-3568 开发板\02_【iTOP-RK3568 开发板】开发资料\10_Linux 系统开发配套资料\05_Linux 修改内核 logo 配套资料”路径下。 5.3.1 准备 logo 系统默认内核 logo&#xff0c;如下图所示&#xff1a; 如 果 想 要 替 换 这 个 logo, 首 先 要 制…

神经网络-pytorch版本

pytorch神经网络基础 torch简介 torch和numpy import torch import numpy as np np_datanp.arange(6).reshape((2,3)) torch_datatorch.from_numpy(np_data) tensor2arraytorch_data.numpy() print(np_data,"\n",torch_data,"\n",tensor2array)torch的数…

2023年已过大半,光通信领域有哪些值得关注的技术趋势?

引言&#xff1a;上个星期&#xff0c;小枣君去深圳参加了CIOE中国光博会&#xff0c;获得了一些光通信领域的最新技术动态进展。今天&#xff0c;我来和大家做一个分享。 这次光博会&#xff0c;整个行业的参与热情很高。据主办方统计&#xff0c;为期三天的展会&#xff0c;现…

Android 11.0 系统system模块开启禁用adb push和adb pull传输文件功能

1.使用场景 在进行11.0的系统定制化开发中,在一些产品中由于一些开发的功能比较重要,防止技术点外泄在出货产品中,禁用 adb pull 和adb push等命令 来获取系统system下的jar 和apk 等文件,所以需要禁用这些命令 2.系统system模块开启禁用adb push和adb pull传输文件功能的…

球谐函数实现环境光照漫反射实践

该文章以及代码主要来自 图形学论文解析与复现&#xff1a;【论文复现】An Efficient Representation for Irradiance Environment Maps 作者&#xff1a;Monica的小甜甜 与原文的不同&#xff1a; 对一些有问题的地方进行了修改添加了注释对有疑问的地方添加了疑问点引入了其…

解决 Elasticsearch 分页查询记录超过10000时异常

查询结果中 hits.total.value 值最大为10000的限制 解决方法: 1、请求设置rest_total_hits_as_inttrue 注意参数需要放在请求头上 builder.addHeader("rest_total_hits_as_int","true"); 2、修改setting的值 #设置返回最大记录条数为1000000 PUT /in…

基于python解决鸡兔同笼问题

一、什么是鸡兔同笼问题&#xff1f; 鸡兔同笼问题是一个经典的数学问题。问题描述&#xff1a;鸡和兔子共有头数a和脚数b&#xff0c;求鸡和兔子的数量。 解析&#xff1a;设鸡的数量为x&#xff0c;兔子的数量为y&#xff0c;那么可以得到以下两个方程&#xff1a; 1. x y…

详解爬虫策略,反爬虫策略,反反爬爬虫策略

爬虫策略 爬取策略是网络爬虫在执行网页抓取任务时所遵循的规则或策略。这些策略决定了爬虫如何从一个页面转到另一个页面&#xff0c;什么时间进行抓取&#xff0c;以及应该抓取哪些内容。以下是几种常见的爬取策略&#xff1a; 深度优先搜索&#xff08;DFS&#xff09; 在…

对抗生成网络总结

对一些基本的对抗生成网络的总结。部分内容整理自Teeyohuang’s blog 文章目录 GAN (NeurIPS, 2014)CGANDCGANStackGANPix2Pix (CVPR, 2017)CycleGAN (ICCV, 2017)SRGAN (CVPR, 2017)StyleGAN (CVPR, 2019) GAN (NeurIPS, 2014) Generative adversarial nets m i n G m a x D …

leetcode top 100 (8)无重复字符的最长子串(滑动窗口

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。 package TOP1_10;import java.util.HashMap; import java.…

Tokenview X-ray功能:深入探索EVM系列浏览器的全新视角

Tokenview作为一家领先的多链区块浏览器&#xff0c;为了进一步优化区块链用户的使用体验&#xff0c;我们推出了X-ray&#xff08;余额透视&#xff09;功能。该功能将帮助您深入了解EVM系列浏览器上每个地址的交易过程&#xff0c;以一种直观、简洁的方式呈现地址的进出账情况…

LCP 50.宝石补给

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCP 50. 宝石补给 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 模拟操作即可。 解题代码&#xff1a; class Solution {public int giveGem(int[] gem, int[][] operations) {for(int[…

002 Linux 权限

前言 本文将会向您介绍关于linux权限方面的内容&#xff0c;包括文件类型&#xff0c;如何切换用户、基本权限、粘滞位等等 Linux具体的用户 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的…

Pytorch intermediate(四) Language Model (RNN-LM)

前一篇中介绍了一种双向的递归神经网络&#xff0c;将数据进行正序输入和倒序输入&#xff0c;兼顾向前的语义以及向后的语义&#xff0c;从而达到更好的分类效果。 之前的两篇使用递归神经网络做的是分类&#xff0c;可以发现做分类时我们不需要使用时序输入过程中产生的输出&…

SSM - Springboot - MyBatis-Plus 全栈体系(八)

第二章 SpringFramework 四、SpringIoC 实践和应用 4. 基于 配置类 方式管理 Bean 4.4 实验三&#xff1a;高级特性&#xff1a;Bean 注解细节 4.4.1 Bean 生成 BeanName 问题 Bean 注解源码&#xff1a; public interface Bean {//前两个注解可以指定Bean的标识AliasFor…

思科的简易配置

vlan 划分配置 1. 拓扑连接 2. 终端设备配置&#xff0c;vlan(v2, v3)配置&#xff0c;模式设置 然后设置交换机 fa 0/5 口为 trunk 模式&#xff0c;使得不同交换机同一 vlan 下 PC 可以互连 3.测试配置结果 用 ip 地址为 192.168.1.1 的主机(PC0)向同一 vlan(v2)下的 192.…

Binder进程通信基础使用

Binder 进程通信基础使用 一、服务端进程创建 Service&#xff0c;Service 中创建 Binder 子类对象并于 onBind 中返回。xml 定义。 创建 Service&#xff0c;创建 Binder 子类对象并于 onBind 返回 class UserService : Service() {private companion object {const val TAG…

BI与数据治理以及数据仓库有什么区别

你可能已经听说过BI、数据治理和数据仓库这些术语&#xff0c;它们在现代企业中起着重要的作用。虽然它们都与数据相关&#xff0c;但它们之间有着明显的区别和各自独特的功能。数聚将详细探讨BI&#xff08;商业智能&#xff09;、数据治理和数据仓库之间的区别&#xff0c;帮…