JavaSE 8基础知识(一)Java8新特性之lambda表达式详解

Java SE 8都有哪些新特性,包括哪些内容(一)?

本文内容参考自Java8标准
再次感谢尚硅谷教学资料对本文的启发!
接着上一篇博文的内容,在上一篇博文中提到,为了适应不断变化的需求(根据年龄筛选集合或者根据收入筛选集合或者根据其它内容等),我们特意创建了一个接口MyPredicate< T >来代表这种需求,同时将这个接口类型放入了主体方法的形式参数中,以便在调用主体方法的时候,能传入不同的实际需求的对象(多态,这些需求对象的类都必须implements这个接口),在最后的测试环节中引出了lambda表达式(本该传一个实际需求的对象,我们直接传入了一个lambda表达式)

①、先规定一个接口

在上一篇博文中规定这个接口是代表需求类型:MyPredicate< T >,但是在这篇博文中,这个接口是为lambda表达式准备的。

   //为使用lambda表达式准备的接口,实际上它代表的还是需求。
   public interface MyPredicate<T>{
      //这里为什么规定方法的返回值为boolean类型
      //继续往下看就知道了,因为这个方法
      //需要在if语句中使用。
      boolean test(T t);
   }
②、再规定一个方法(WorkOnAll(List list,MyPredicate m)),这个接口是这个方法的形式参数,同时创建一个集合list,进行测试
//类FirstWithLambda
   public class FirstWithLambda {
      //方法WorkOnAll(List<Employees> list,
      //MyPredicate<Employees> m),带两个形式参数,一个是List<Employees>
      //类型的list,一个是MyPredicate<Employees>类型的m
      public List<Employees> WorkOnAll(List<Employees> list,
      MyPredicate<Employees> m){
         //创建另外的一个List<Employees> 类型的list1接收
	     //m.test(e)结果为true的Employees对象
         List<Employees> list1 = new ArrayList<>();
           //使用foreach循环list
		   for(Employees e:list) {
		      //判断e是否符合接口MyPredicate<T>
		      //规定的条件,如果符合,m.test(e)结果为true,
		      //如果不符合,结果为false
		      if(m.test(e)) {
		         //m.test(e)结果为true,将对象e添加到
		         //容器list1中.
		         list1.add(e);
		      }
	       }
	       //返回容器list1
	       return list1;
      }
   }
      //利用Employees对象创建一个List类型的集合(这里还使用了类
      //Arrays的方法asList(T...a)进行了转换)。
      //注意使用泛型
      List<Employees> list = Arrays.asList(
         new Employees("张三",18,9999.99),
         new Employees("李四",38,5555.55),
		 new Employees("王五",50,6666.66),
		 new Employees("赵六",16,3333.33),
		 new Employees("田七",8,8888.88)
	  ); 
      //程序执行入口main方法
      public static void main(String[] args){ 
		 //创建类FirstWithoutLambda的对象
         FirstWithLambda f = new FirstWithLambda();
		 //调用类TestAll的方法WorkOn(List<Employees> list,
		 //MyPredicate<Employees> m),传入实际参数list和一个一个lambda表达式
		 List<Employees> list11 = t.WorkOn(f.list, (e)->e.getAge()>35);
		 //打印容器list11
		 System.out.println(list11);
	  }
   }

你会发现,在需要传一个接口类型的实际调用中,只传入了一个lambda表达式就解决了问题:
一个lambda表达式代替了一个接口类型

这就是lambda表达式看起来的样子:(e)->e.getAge()>35

重点是这个符号:"->",它是lambda表达式特有的。
那么这个符号的左边(e)和右边(e.getAge()>35)分别是什么呢?
实际上,lambda表达式符号("->")左边的部分是它的参数,而右边的部分是lambda体,也就是这个lambda表达式需要执行的代码。
那么lambda表达式的参数和lambda体分别有什么规则呢?分以下几步来看:

⑴、lambda表达式需要一个"函数式"接口的支持。

什么叫"函数式"接口呢?“函数式"接口指的是只有一个方法的接口(也就是这个接口里面只有一个方法需要实现),比如上面的代码示例中的接口(MyPredicate< T >):它只有一个需要实现的方法(test(T t))。
函数式接口
那么,接下来的内容就很简单了。
再回到上面代码示例中的主体方法(WorkOnAll(List< Employees > list, MyPredicate< Employees > m)),在调用它的时候,需要传入两个实际参数,一个是List< Employees >类型的list对象,一个是实现了MyPredicate< Employees >接口的类的对象,list对象好理解,重点在:实现了MyPredicate< Employees >接口的类的对象
在上一篇博文中,我分别尝试了三种方式:
①、用一个类去实现接口MyPredicate< Employees >,然后创建这个类的对象作为实际参数传入方法WorkOnAll(List< Employees > list, MyPredicate< Employees > m)。
②、在调用方法WorkOnAll(List< Employees > list, MyPredicate< Employees > m)的时候直接使用一个匿名内部类
③、在调用方法WorkOnAll(List< Employees > list, MyPredicate< Employees > m)的时候直接使用一个lambda表达式
你会发现,在以上三种方式中,接口MyPredicate< Employees >的方法test(T t)的形式参数t都是重点,无论哪种方式它都是核心,而lambda表达式是最简代码表示,所以:lambda表达式符号”->"左边的内容是传入这个函数式接口的方法的实际参数(接口MyPredicate< Employees >的方法test(T t)使用了泛型,所以用T表示,而实际传入的参数是类Employees对象,所以最终的lambda表达式中的e表示的就是一个类Employees的对象)。

图示

1、一个类implements接口MyPredicate< Employees >的参数
创建一个实现接口的类
2、匿名内部类的参数
匿名内部类
3、lambda表达式的参数
在这里插入图片描述

你还会发现,在以上三种方式中,接口MyPredicate< Employees >的方法test(T t)的实现是除参数t外的另一个重点,无论使用哪种方式,你总是需要为方法test(T t)提供一个实现的,而lambda方式仍然是最简代码表示。

图示

1、一个类implements接口MyPredicate< Employees >的实现
一个类implements接口MyPredicate< Employees >的实现
2、匿名内部类的实现
匿名内部类的实现
3、lambda表达式的实现
lambda表达式的实现

你会发现lambda表达式是实现一个函数式接口的最简方式,一句多余的代码都没有(仅有参数和实现,实际上,它除了一个特有的符号,也没有任何的关键字)。

⑵、lambda表达式的参数数量与函数式接口的方法中声明的形式参数的数量完全一致。

因为方法除了参数以外,还涉及到是否有返回值的问题,下面通过举例来说明所有的情况
①、函数式接口的方法既没有形式参数,也没有返回值。

// 方法既没有参数,也没有返回值的函数式接口
   public interface MyPredicate<T>{
      void test();
   }
   //-----------------------------------------------------
   //lambda表达式的使用形式
   ()->System.out.println("Hello Lambda");
   //没有任何参数,lambda表达式左边就用()表示,右边就随意提供一些实现就行
   //在标准JavaAPI中,接口Runnable就属于这种类型
   //没有lambda表达式时使用接口Runnable的代码:
   Runnable r = new Runnable(){
      public void run(){
         System.out.println("Hello Lambda");
      }
   };
   //通过lambda表达式使用Runnable接口
   Runnable r1 = ()->System.out.println("Hello Lambda");

结果示例:
结果示例

内容概要:本文档详细介绍了在三台CentOS 7服务器(IP地址分别为192.168.0.157、192.168.0.158和192.168.0.159)上安装和配置Hadoop、Flink及其他大数据组件(如Hive、MySQL、Sqoop、Kafka、Zookeeper、HBase、Spark、Scala)的具体步骤。首先,文档说明了环境准备,包括配置主机名映射、SSH免密登录、JDK安装等。接着,详细描述了Hadoop集群的安装配置,包括SSH免密登录、JDK配置、Hadoop环境变量设置、HDFS和YARN配置文件修改、集群启动与测试。随后,依次介绍了MySQL、Hive、Sqoop、Kafka、Zookeeper、HBase、Spark、Scala和Flink的安装配置过程,包括解压、环境变量配置、配置文件修改、服务启动等关键步骤。最后,文档提供了每个组件的基本测试方法,确保安装成功。 适合人群:具备一定Linux基础和大数据组件基础知识的运维人员、大数据开发工程师以及系统管理员。 使用场景及目标:①为大数据平台建提供详细的安装指南,确保各组件能够顺利安装和配置;②帮助技术人员快速掌握Hadoop、Flink等大数据组件的安装与配置,提升工作效率;③适用于企业级大数据平台的建与维护,确保集群稳定运行。 其他说明:本文档不仅提供了详细的安装步骤,还涵盖了常见的配置项解释和故障排查建议。建议读者在安装过程中仔细阅读每一步骤,并根据实际情况调整配置参数。此外,文档中的命令和配置文件路径均为示例,实际操作时需根据具体环境进行适当修改。
在无线通信领域,天线阵列设计对于信号传播方向和覆盖范围的优化至关重要。本题要求设计一个广播电台的天线布局,形成特定的水平面波瓣图,即在东北方向实现最大辐射强度,在正东到正北的90°范围内辐射衰减最小且无零点;而在其余270°范围内允许出现零点,且正西和西南方向必须为零。为此,设计了一个由4个铅垂铁塔组成的阵列,各铁塔上的电流幅度相等,相位关系可自由调整,几何布置和间距不受限制。设计过程如下: 第一步:构建初级波瓣图 选取南北方向上的两个点源,间距为0.2λ(λ为电磁波波长),形成一个端射阵。通过调整相位差,使正南方向的辐射为零,计算得到初始相位差δ=252°。为了满足西南方向零辐射的要求,整体相位再偏移45°,得到初级波瓣图的表达式为E1=cos(36°cos(φ+45°)+126°)。 第二步:构建次级波瓣图 再选取一个点源位于正北方向,另一个点源位于西南方向,间距为0.4λ。调整相位差使西南方向的辐射为零,计算得到相位差δ=280°。同样整体偏移45°,得到次级波瓣图的表达式为E2=cos(72°cos(φ+45°)+140°)。 最终组合: 将初级波瓣图E1和次级波瓣图E2相乘,得到总阵的波瓣图E=E1×E2=cos(36°cos(φ+45°)+126°)×cos(72°cos(φ+45°)+140°)。通过编程实现计算并绘制波瓣图,可以看到三个阶段的波瓣图分别对应初级波瓣、次级波瓣和总波瓣,最终得到满足广播电台需求的总波瓣图。实验代码使用MATLAB编写,利用polar函数在极坐标下绘制波瓣图,并通过subplot分块显示不同阶段的波瓣图。这种设计方法体现了天线阵列设计的基本原理,即通过调整天线间的相对位置和相位关系,控制电磁波的辐射方向和强度,以满足特定的覆盖需求。这种设计在雷达、卫星通信和移动通信基站等无线通信系统中得到了广泛应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值