React 全栈体系(十一)
第五章 React 路由
五、向路由组件传递参数数据
1. 效果

2. 代码 - 传递 params 参数
2.1 Message
/* src/pages/Home/Message/index.jsx */
import React, { Component } from "react";
import {Link, Route} from 'react-router-dom'
import Detail from './Detail'export default class Message extends Component {state = {messageArr: [{id:'01', title: '消息1'},{id:'02', title: '消息2'},{id:'03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj)=>{return (<li key={msgObj.id}>{/* 向路由组件传递params参数 */}<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link></li>)})}</ul><hr />{/* 声明接收params参数 */}<Route path="/home/message/detail/:id/:title" component={Detail}/></div>);}
}
2.2 Detail
/* src/pages/Home/Message/Detail/index.jsx */
import React, { Component } from 'react'const Detaildata = [{id:'01', content:'你好,中国'},{id:'02', content:'你好,小帽学堂'},{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {render() {//接收params参数const {id, title} = this.props.match.paramsconst findResult = Detaildata.find((detailObj)=>{return detailObj.id === id})return (<ul><li>ID:{id}</li><li>Title:{title}</li><li>Content: {findResult.content}</li></ul>)}
}
3. 代码 - 传递 search 参数
3.1 Message
/* src/pages/Home/Message/index.jsx */
import React, { Component } from "react";
import {Link, Route} from 'react-router-dom'
import Detail from './Detail'export default class Message extends Component {state = {messageArr: [{id:'01', title: '消息1'},{id:'02', title: '消息2'},{id:'03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj)=>{return (<li key={msgObj.id}>{/* 向路由组件传递params参数 */}{/* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}{/* 向路由组件传递search参数 */}<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link></li>)})}</ul><hr />{/* 声明接收params参数 */}{/* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}{/* search参数无需声明接收,正常注册路由即可 */}<Route path="/home/message/detail" component={Detail}/></div>);}
}
3.2 Detail
/* src/pages/Home/Message/Detail/index.jsx */
import React, { Component } from 'react'
import qs from 'querystring'const Detaildata = [{id:'01', content:'你好,中国'},{id:'02', content:'你好,小帽学堂'},{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {render() {// 接收params参数// const {id, title} = this.props.match.params// 接收search参数const {search} = this.props.locationconst {id, title} = qs.parse(search.slice(1))const findResult = Detaildata.find((detailObj)=>{return detailObj.id === id})return (<ul><li>ID:{id}</li><li>Title:{title}</li><li>Content: {findResult.content}</li></ul>)}
}
4. 代码 - 传递 state 参数
4.1 Message
/* src/pages/Home/Message/index.jsx */
import React, { Component } from "react";
import {Link, Route} from 'react-router-dom'
import Detail from './Detail'export default class Message extends Component {state = {messageArr: [{id:'01', title: '消息1'},{id:'02', title: '消息2'},{id:'03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj)=>{return (<li key={msgObj.id}>{/* 向路由组件传递params参数 */}{/* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}{/* 向路由组件传递search参数 */}{/* <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> */}{/* 向路由组件传递state参数 */}<Link to={{pathname:'/home/message/detail', state:{id:msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr />{/* 声明接收params参数 */}{/* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}{/* search参数无需声明接收,正常注册路由即可 */}{/* <Route path="/home/message/detail" component={Detail}/> */}{/* state参数无需声明接收,正常注册路由即可 */}<Route path="/home/message/detail" component={Detail}/></div>);}
}
4.2 Detail
/* src/pages/Home/Message/Detail/index.jsx */
import React, { Component } from 'react'
// import qs from 'querystring'const Detaildata = [{id:'01', content:'你好,中国'},{id:'02', content:'你好,小帽学堂'},{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {render() {// 接收params参数// const {id, title} = this.props.match.params// 接收search参数// const {search} = this.props.location// const {id, title} = qs.parse(search.slice(1))// 接收state参数const {id, title} = this.props.location.state || {}const findResult = Detaildata.find((detailObj)=>{return detailObj.id === id}) || {}return (<ul><li>ID:{id}</li><li>Title:{title}</li><li>Content: {findResult.content}</li></ul>)}
}
5. 总结
1.params参数路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>接收参数:this.props.match.params2.search参数路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>接收参数:this.props.location.search备注:获取到的search是urlencoded编码字符串,需要借助querystring解析3.state参数路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>接收参数:this.props.location.state备注:刷新也可以保留住参数
6. 代码 - push 与 replace 模式
Message
/* src/pages/Home/Message/index.jsx */
import React, { Component } from "react";
import {Link, Route} from 'react-router-dom'
import Detail from './Detail'export default class Message extends Component {state = {messageArr: [{id:'01', title: '消息1'},{id:'02', title: '消息2'},{id:'03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj)=>{return (<li key={msgObj.id}>{/* 向路由组件传递params参数 */}{/* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}{/* 向路由组件传递search参数 */}{/* <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> */}{/* 向路由组件传递state参数 */}<Link replace to={{pathname:'/home/message/detail', state:{id:msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr />{/* 声明接收params参数 */}{/* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}{/* search参数无需声明接收,正常注册路由即可 */}{/* <Route path="/home/message/detail" component={Detail}/> */}{/* state参数无需声明接收,正常注册路由即可 */}<Route path="/home/message/detail" component={Detail}/></div>);}
}
六、多种路由跳转方式
1. 效果

2. 代码 - 跳转 + 携带 params 参数
2.1 Message
/* src/pages/Home/Message/index.jsx */
import React, { Component } from "react";
import { Link, Route } from "react-router-dom";
import Detail from "./Detail";export default class Message extends Component {state = {messageArr: [{ id: "01", title: "消息1" },{ id: "02", title: "消息2" },{ id: "03", title: "消息3" },],};pushShow = (id, title) => {//push跳转+携带params参数this.props.history.push(`/home/message/detail/${id}/${title}`)}replaceShow = (id, title) => {//replace跳转+携带params参数this.props.history.replace(`/home/message/detail/${id}/${title}`)}render() {const { messageArr } = this.state;return (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/* 向路由组件传递params参数 */}<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> <button onClick={()=>this.pushShow(msgObj.id, msgObj.title)}>push查看</button> <button onClick={()=>this.replaceShow(msgObj.id, msgObj.title)}>replace查看</button></li>);})}</ul><hr />{/* 声明接收params参数 */}<Route path="/home/message/detail/:id/:title" component={Detail} /></div>);}
}
2.2 Detail
/* src/pages/Home/Message/Detail/index.jsx */
import React, { Component } from 'react'
// import qs from 'querystring'const Detaildata = [{id:'01', content:'你好,中国'},{id:'02', content:'你好,小帽学堂'},{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {render() {// 接收params参数const {id, title} = this.props.match.paramsconst findResult = Detaildata.find((detailObj)=>{return detailObj.id === id}) || {}return (<ul><li>ID:{id}</li><li>Title:{title}</li><li>Content: {findResult.content}</li></ul>)}
}
3. 代码 - 跳转 + 携带 state 参数
3.1 Message
/* src/pages/Home/Message/index.jsx */
import React, { Component } from "react";
import { Link, Route } from "react-router-dom";
import Detail from "./Detail";export default class Message extends Component {state = {messageArr: [{ id: "01", title: "消息1" },{ id: "02", title: "消息2" },{ id: "03", title: "消息3" },],};pushShow = (id, title) => {//push跳转+携带state参数this.props.history.push(`/home/message/detail`, {id,title})}replaceShow = (id, title) => {//replace跳转+携带state参数this.props.history.replace(`/home/message/detail`, {id,title})}render() {const { messageArr } = this.state;return (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/* 向路由组件传递params参数 */}<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id, title:msgObj.title}}}>{msgObj.title}</Link> <button onClick={()=>this.pushShow(msgObj.id, msgObj.title)}>push查看</button> <button onClick={()=>this.replaceShow(msgObj.id, msgObj.title)}>replace查看</button></li>);})}</ul><hr />{/* 声明接收state参数 */}<Route path="/home/message/detail" component={Detail} /></div>);}
}
3.2 Detail
/* src/pages/Home/Message/Detail/index.jsx */
import React, { Component } from 'react'const Detaildata = [{id:'01', content:'你好,中国'},{id:'02', content:'你好,小帽学堂'},{id:'03', content:'你好,未来的自己'}
]
export default class Detail extends Component {render() {const {id, title} = this.props.location.stateconst findResult = Detaildata.find((detailObj)=>{return detailObj.id === id})return (<ul><li>ID:{id}</li><li>Title:{title}</li><li>Content: {findResult.content}</li></ul>)}
}
4. 代码 - 前进后退
/* src/pages/Home/Message/index.jsx */
import React, { Component } from "react";
import { Link, Route } from "react-router-dom";
import Detail from "./Detail";export default class Message extends Component {state = {messageArr: [{ id: "01", title: "消息1" },{ id: "02", title: "消息2" },{ id: "03", title: "消息3" },],};pushShow = (id, title) => {//push跳转+携带state参数this.props.history.push(`/home/message/detail`, { id, title });};replaceShow = (id, title) => {//replace跳转+携带state参数this.props.history.replace(`/home/message/detail`, { id, title });};back = () => {this.props.history.goBack();};forward = () => {this.props.history.goForward();};go = () => {this.props.history.go(-2);};render() {const { messageArr } = this.state;return (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/* 向路由组件传递params参数 */}<Linkto={{pathname: "/home/message/detail",state: { id: msgObj.id, title: msgObj.title },}}>{msgObj.title}</Link> <button onClick={() => this.pushShow(msgObj.id, msgObj.title)}>push查看</button> <buttononClick={() => this.replaceShow(msgObj.id, msgObj.title)}>replace查看</button></li>);})}</ul><hr />{/* 声明接收state参数 */}<Route path="/home/message/detail" component={Detail} /><button onClick={this.back}>回退</button> <button onClick={this.forward}>前进</button> <button onClick={this.go}>go</button></div>);}
}
5. 总结
借助this.prosp.history对象上的API对操作路由跳转、前进、后退-this.prosp.history.push()-this.prosp.history.replace()-this.prosp.history.goBack()-this.prosp.history.goForward()-this.prosp.history.go()
6. withRouter 的使用
Header
/* src/components/Header/index.jsx */
import React, { Component } from 'react'
import {withRouter} from 'react-router-dom'class Header extends Component {back = ()=>{this.props.history.goBack()}forward = ()=>{this.props.history.goForward()}go = ()=>{this.props.history.go(-2)}render() {console.log('Header组件收到的props是',this.props);return (<div className="page-header"><h2>React Router Demo</h2><button onClick={this.back}>回退</button> <button onClick={this.forward}>前进</button> <button onClick={this.go}>go</button></div>)}
}export default withRouter(Header)//withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
//withRouter的返回值是一个新组件

七、BrowserRouter 与 HashRouter 的区别
1.底层原理不一样:BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。HashRouter使用的是URL的哈希值。
2.path表现形式不一样BrowserRouter的路径中没有#,例如:localhost:3000/demo/testHashRouter的路径包含#,例如:localhost:3000/#/demo/test
3.刷新后对路由state参数的影响(1).BrowserRouter没有任何影响,因为state保存在history对象中。(2).HashRouter刷新后会导致路由state参数的丢失!!!
4.备注:HashRouter可以用于解决一些路径错误相关的问题。
相关文章:
React 全栈体系(十一)
第五章 React 路由 五、向路由组件传递参数数据 1. 效果 2. 代码 - 传递 params 参数 2.1 Message /* src/pages/Home/Message/index.jsx */ import React, { Component } from "react"; import {Link, Route} from react-router-dom import Detail from ./Detai…...
AI 时代的向量数据库、关系型数据库与 Serverless 技术丨TiDB Hackathon 2023 随想
TiDB Hackathon 2023 刚刚结束,我仔细地审阅了所有的项目。 在并未强调项目必须使用人工智能(AI)相关技术的情况下,引人注目的项目几乎一致地都使用了 AI 来构建自己的应用。 大规模语言模型(LLM)的问世使得…...
Vue的路由使用,Node.js下载安装及环境配置教程 (超级详细)
前言: 今天我们来讲解关于Vue的路由使用,Node.js下载安装及环境配置教程 一,Vue的路由使用 首先我们Vue的路由使用,必须要导入官方的依赖的。 BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务https://www.bootcdn.cn/ <…...
vue修改node_modules打补丁步骤和注意事项
当我们使用 npm 上的第三方依赖包,如果发现 bug 时,怎么办呢? 想想我们在使用第三方依赖包时如果遇到了bug,通常解决的方式都是绕过这个问题,使用其他方式解决,较为麻烦。或者给作者提个issue,然…...
CSS 响应式设计:媒体查询
文章目录 媒体查询添加断点为移动端优先设计其他断点方向:横屏/竖屏 媒体查询 CSS中的媒体查询是一种用于根据不同设备的屏幕尺寸和分辨率来定义样式表的方法。在CSS中,我们可以使用媒体查询来根据不同的设备类型和屏幕尺寸来应用不同的样式,…...
Qt开发 - Qt基础类型
1.基础类型 因为Qt是一个C 框架, 因此C中所有的语法和数据类型在Qt中都是被支持的, 但是Qt中也定义了一些属于自己的数据类型, 下边给大家介绍一下这些基础的数类型。 QT基本数据类型定义在#include <QtGlobal> 中,QT基本数据类型有: 虽然在Qt中…...
Docker-如何获取docker官网x86、ARM、AMD等不同架构下的镜像资源
文章目录 一、概要二、资源准备三、环境准备1、环境安装2、服务器设置代理3、注册docker账号4、配置docker源 四、查找资源1、服务器设置代理2、配置拉取账号3、查找对应的镜像4、查找不同版本镜像拉取 小结 一、概要 开发过程中经常会使用到一些开源的资源,比如经…...
Vuex状态管理最佳实践
文章目录 单一状态树使用模块使用常量定义Mutation类型使用Actions处理异步操作使用Getters计算属性严格模式分模块管理Getter、Mutation和Action:注释和文档:Vue Devtools ✍创作者:全栈弄潮儿 🏡 个人主页: 全栈弄潮…...
platform和led中断项目
设备树根节点下添加 myledIrqPlatform{compatible"hqyj,myledIrqPlatform";reg<0x22334455 59>;interrupt-parent<&gpiof>;interrupts<9 0>;led1-gpio<&gpioe 10 0>;//10表示使用的gpioe第几个管脚 0,表示gpio默认属性…...
R语言-关于颜色
目录 颜色 示例 R 颜色板 参考: 颜色 什么场景会用到颜色?比如在绘图过程中,为了让图更好看,有的时候,需要选择使用不同的颜色进行绘制或者填充。本文提供了R颜色的相关参数。 在R中,可以通过颜色下标…...
抖音seo优化排名源码搭建
抖音seo优化排名技术开发源码搭建: 思路:看上去比较简单,貌似使用 get、set 这两个 trap 就可以,但实际上并不是。实际上还需要实现 has, ownKeys , getOwnPropertyDescriptor 这些 trap,这样就能最大限度的限制私有属…...
pytorch的卷积层池化层和非线性变化 和机器学习线性回归
卷积层: 两个输出的情况 就会有两个通道 可以改变通道数的 最简单的神经网络结构: nn.Mudule就是继承父类 super执行的是 先执行父类函数里面的 forward执行的就是前向网络,就是往前推进的,当然也有反向转播,那就是…...
Java手写快速选择算法应用拓展案例
Java手写快速选择算法应用拓展案例 1. 引言 快速选择算法是一种高效的选择算法,可以用于在数组中找到第K小/大的元素。除了基本的应用场景外,快速选择算法还可以应用于其他问题,如查找中位数、查找最大/最小值等。本文将介绍两个拓展应用案…...
js制作柱状图的x轴时间, 分别展示 月/周/日 的数据
背景 有个需求是要做一个柱状图, x 轴是时间, y 轴是数量. 其中 x 轴的时间有三种查看方式: 月份/周/日, 也就是分别查看从当前日期开始倒推的最近每月/每周/每日的数量. 本篇文章主要是用来制作三种不同的 x 轴 从当前月开始倒推月份 注意 getMonth() 函数可以获取当前月份…...
安防监控/视频汇聚/云存储/AI智能视频分析平台EasyCVR下级海康设备无法级联是什么原因?
安防视频监控平台/视频集中存储/云存储/磁盘阵列EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。 有用户反馈&…...
HttpUtils带连接池
准备祖传了,有问题欢迎大家指正。 HttpUtil import com.txlc.cloud.commons.exception.ServiceException; import com.txlc.dwh.common.constants.MyErrorCode; import org.ssssssss.script.annotation.Comment;import java.io.UnsupportedEncodingException; impo…...
智慧养殖:浅谈视频监控与AI智能识别技术助力奶牛高效、智慧养殖
一、方案背景 随着科技的飞速发展,智能化养殖逐渐成为现代畜牧业的发展趋势。人工智能技术、物联网、视频技术、云计算、大数据等新兴技术,正在为奶牛养殖业带来全新的变革。越来越多的牧场、养殖场开始运用新技术来进行智能监管、提高生产效率、降低生…...
一文总结提示工程框架,除了CoT还有ToT、GoT、AoT、SoT、PoT
夕小瑶科技说 原创 编译 | 谢年年 大语言模型LLM被视为一个巨大的知识库,它可以根据你提出问题或陈述的方式来提供答案。就像人类可能会根据问题的不同提供不同的答案一样,LLM也可以根据输入的不同给出不同的答案。因此,你的问题或陈述方式就…...
Java面试笔试acm版输入
首先区分scanner.nextInt()//输入一个整数,只能读取一个数,空格就停止。 scanner.next()//输入字符串,只能读取一个字符串,空格就停止,但是逗号不停止。 scanner.nextLine() 读取一行,换行停止,…...
新手怎样快速上手接口测试?掌握这几个知识点直接起飞!
接口测试是测试系统组件间接口的一种方式,接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是检查数据的增删改查操作,以及系统之间的逻辑关系等。 接口的几种类型 接口的类型包括:post ,get&…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...
