Lambda表达式、File类

今日内容

  • 函数式编程思想
  • lambda表达式
  • File类

Lambda表达式

函数式编程思想

强调的是做什么,而不是以什么样的方式来做,它忽略了面向对象的复杂语法,只要能够获取到结果,谁去做的,怎么做的,都不重要,重要的是结果,不重视过程

冗余的Runnable代码

传统的写法

public class Demo01Runnable{
    public static void main(String[] args){
        // 匿名内部类的方式
        new Thread(new Runnable(){
        @Override
            public void run(){
                System.out.println("开启一个新线程的任务");
            }
            
        }).start();
    }
}
代码分析

对于Runnable的匿名内部类用法,可以分析出一下内容:

  • Thread类需要Runnable接口作为参数,其中抽象方法run用来指定线程任务内容的核心。
  • 为了指定run方法的方法体,不得不需要Runnable接口的实现类
  • 为了省去定义一个RunnableImpl实现类的麻烦,不得不使用匿名内部类
  • 必须重写抽象方法run方法,所有方法的名称,方法的参数,方法的返回值不得不写一遍,且不能写错
  • 从这里面可以看出,只有方法体才是线程任务的关键性内容
编程思想的转换

做什么,而不是怎么做

我们真正希望做的事情是:将run方法体内的代码传递给Thread类知晓能够加载到即可。

传递一段代码—这是我们真正的目的

我们需要将程序关注的重点从怎么做回归到做什么的本质上,过程与形式并不重要。

2014年3月Oracle官方所发布的Java 8(JDK1.8)中,加入了Lambda表达式

体验Lambda表达式的更优写法
public class Demo01Runnable{
public static void main(String[] args){
new Thread(() ->{
    System.out.println("开启新线程");
}).start;
}
}

从上面的代码可以看出:没有创建接口实现类对象的操作,也不再有抽象方法覆盖重写的操作,只写了线程任务的内容

从上面的代码能够推导出Lambda的语法

() -> System.out.println("开启新线程");
  • 前面的一对小括号即run方法,参数为无,里面是空的,此时不需要任何的条件
  • 中间的一个箭头代表将前面的参数传递给后面的代码
  • 后面的输出语句即业务逻辑代码(线程任务内容)
Lambda的标准格式

格式由三个部分组成:

lambda表达式的标准格式
   由三部分组成:
    a: 一些参数:0,1,....n
    b: 一个箭头
    c: 一段代码
    格式:
    (参数列表) -> {一些重写方法的代码};
    格式说明:
    ():接口中抽象方法,参数列表可以没有参数,就空着,有参数就写出参数,多个参数使用逗号隔开
    ->:传递的意思,把方法中的参数传递给方法体{}  代表指向的动作
    {}:重写接口的抽象方法的方法体
    小括号内的语法与传统的方法参数列表一致,无参数就留空,多个参数则用逗号隔开
    大括号内的语法与传统方法体要求基本一致    

Lambda表达式的标准格式:

(参数类型1 参数名称1,参数类型2 参数名称2,....) -> {代码语句}

格式说明:

小括号内的语法与传统的方法参数列表一致,无参数就留空,多个参数则用逗号隔开

->是新引入的语法格式,代表指向的动作

大括号内的语法与传统方法体要求基本一致

练习:定义一个厨子接口,该接口内内置了一个做饭的方法(抽象的方法),且无参数,无返回值,使用Lambda表达式,最后打印输出“我今天吃的是红烧茄子,吃的好开心”。(无参无返回)

练习2:使用数组存储多个学生对象,对数组中的学生对象使用Arrays的sort方法通过年龄进行升序排序。使用Lambda表达式来实现以上需求。(有参无返回)

练习3:给定一个计算器接口,内置了一个抽象方法计算的方法,可以将两个double类型的数字相加得到和值。使用Lambda表达式来实现以上需求。(有参有返回)

代码示例:

1:

package com.zhiyou100.Lambda.demo01;
/*
 * 定义一个接口 厨子接口,内含唯一的抽象方法做饭的方法 makeFood()
 */
public interface Cook {
	// 定义一个无参无返回的方法	
	void makeFood();	
}

package com.zhiyou100.Lambda.demo01;
/*
 * 
 * 定义一个厨子接口,该接口内内置了一个做饭的方法(抽象的方法),且无参数,无返回值,
 * 使用Lambda表达式,最后打印输出“我今天吃的是红烧茄子,吃的好开心”。(无参无返回)
 * 标准格式:
 *   (参数类型1 参数名称1,参数类型2 参数名称2,....) -> {代码语句}
 */
public class Demo01Cook {

   public static void main(String[] args) {
      //调用invokeFood()方法,参数是Cook接口, 传递Cook接口的匿名内部类对象
      invokeFood(new Cook() {
         @Override
         public void makeFood() {
            System.out.println("我今天吃的是红烧茄子,吃的好开心");
         }
      });
      
//    () ->{};
      // 使用Lambda表达式,简化匿名内部类
      invokeFood(() -> {
         System.out.println("我今天吃的是红烧茄子,吃的好开心");
      });
      
      // 使用Lambda表达式的省略写法
      invokeFood(() -> System.out.println("我今天吃的是红烧茄子,吃的好开心"));
      
   
   }
   
   // 定义一个方法,参数的类型Cook接口,方法内部做一个调用makeFood()
   public static void invokeFood(Cook cook) {
      cook.makeFood();
   }
 
}

2:

package com.zhiyou100.Lambda.demo02;
//定义一个学生类
public class Student {
	private String name;
	private Integer age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	public Student(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public Student() {
		super();
	}

}

package com.zhiyou100.Lambda.demo02;

import java.util.Arrays;
import java.util.Comparator;

/*
 * 使用数组存储多个学生对象,对数组中的学生对象使用Arrays的sort方法通过年龄进行升序排序。
 * 使用Lambda表达式来实现以上需求。(有参无返回)
 * 
 */
public class Demo01Arrays {

	public static void main(String[] args) {
		// 使用数组存储多个学生对象
		Student[] students = {new Student("小孙", 20),new Student("小刘", 18),
				   new Student("小王",25),new Student("小赵", 15)};
		
		// 传统的写法 匿名内部类方式
		/*Arrays.sort(students,new Comparator<Student>(){
			// 升序     前面-后面
			@Override
			public int compare(Student s1,Student s2) {
				return s1.getAge() - s2.getAge();
			}
		});*/
		
		// 使用Lambda表达式 简化匿名内部类
		Arrays.sort(students,(Student s1,Student s2) -> {
			return s1.getAge() - s2.getAge();
		});
		
		// 使用Lambda表达式的省略写法
		Arrays.sort(students,(s1,s2) -> s1.getAge() - s2.getAge());
		
		
		/*输出的结果:
		 *  Student [name=小赵, age=15]
			Student [name=小刘, age=18]
			Student [name=小孙, age=20]
			Student [name=小王, age=25]
		 */
		
		for (Student student : students) {
			System.out.println(student);
		}
		
	}
}

3:

package com.zhiyou100.Lambda.demo03;
//定义一个计算器的接口Cala,内置了一个抽象的方法 sum(double d1,double d2),有返回值sum值
public interface Calc {
   // 定义一个求和的 
   double sum(double d1,double d2);
   
}
package com.zhiyou100.Lambda.demo03;

import java.util.Arrays;
import java.util.Comparator;

import com.zhiyou100.Lambda.demo02.Student;

/*
 * 给定一个计算器接口,内置了一个抽象方法计算的方法,可以将两个double类型的数字相加得到和值。
 * 使用Lambda表达式来实现以上需求。(有参有返回)
 * 
 */
public class Demo01Calc {

	public static void main(String[] args) {
		
		// 传统写法  使用匿名内部类的方式
		/*invokeSum(3.14, 3.15, new Calc() {
			@Override
			public double sum(double d1, double d2) {
				
				return d1 + d2;
			}
		});*/ // d1 + d2 的和为:6.29
		
//		() -> {}
		// 使用Lambda表达式实现      新式写法
		/*invokeSum(3.14, 3.15, (double d1,double d2) -> {
			   // 带着返回值
			   return  d1 + d2;
		});*/// d1 + d2 的和为:6.29
		
		// 使用Lambda表达式的省略写法
		invokeSum(3.14,3.15,(d1,d2) -> d1 + d2);
		
	}
	
	// 定义一个方法
	/*
	 * 参数传递两个double值,
	 * 传递一个Calc接口
	 * 方法内部调用了sum()
	 * 
	 */
	public static void invokeSum(double d1,double d2,Calc calc) {
		double sum = calc.sum(d1, d2);
		System.out.println("d1 + d2 的和为:"+sum);
	}
}

Lambda省略格式

可推导即可省略

Lambda强调的是"做什么",而不是"怎么做",所以凡是可以根据上下文推导得知的信息,都可以省略。

比如:

invokeSum(3.14, 3.15, (double d1,double d2) -> {
			   return  d1 + d2;
		});
// 省略格式表达
invokeSum(3.14,3.15,(d1,d2) -> d1 + d2);

省略的规则:

在Lambda标准格式的表达式的基础上,使用省略写法的规则是:

  1. 小括号内参数的类型可以省略。
  2. 如果小括号内有且仅有一个参数,则小括号也可以省略
  3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字和语句的分号。
Lambda的使用前提

Lambda的语法非常的简洁,使用非常的简单,但是有以下注意事项:

  1. 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法

    无论JDK内置的Runnable、Comparator接口还是自定义的接口,只有当接口中的抽象方法存在且唯一,才可以使用Lambda

  2. 使用Lambda必须具有***上下文推断***。

    也就是方法的参数或者局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。

备注:有且仅有一个抽象方法的接口,称为函数式接口

File类
概述

java.io.File类是文件和目录路径名的抽象表示。主要用于文件和目录的创建、查找、删除等操作。

Java把电脑中的文件和文件夹(目录)封装为了一个File类,我们可以使用File类对文件和文件夹进行操作。

可以使用File类的方法:

  • 创建一个文件、文件夹

  • 删除一个文件、文件夹

  • 获取一个文件、文件夹

  • 判断文件、文件夹是否存在

  • 对文件夹进行遍历

  • 获取文件的大小

    File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法。

构造方法摘要 
public File(File parent, String child) 
          根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 
public File(String pathname) 
          通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。 
public File(String parent, String child) 
          根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 
常用API方法
  • 获取功能的方法
  • 判断功能的方法
  • 路径功能的方法
  • 创建删除功能的方法
  • 目录遍历功能的方法
获取功能的方法
  • public String getAbsolutePath():返回此抽象路径名的绝对路径名字符串。
  • public String getPath():将此File转换为路径名字符串
  • public String getName():返回由此File表示的文件或目录的名称。
  • public long length():返回此File表示的文件的长度。
判断功能的方法
  • public boolean exists():判断File表示的文件或者文件夹是否实际存在
  • public boolean isDirectory():判断此File表示的文件夹是否存在
  • public boolean isFile():判断此File表示的文件是否存在
创建和删除文件的方法
  • public boolean createNewFile():当且仅当具有该名称的文件不存在时,创建一个新的空的文件,返回值是true
  • public boolean delete():删除由此File表示的文件或者目录
  • public boolean mkdir():创建由此File表示的文件夹
  • public boolean mkdirs():创建由此File表示的文件夹,包括任何必须但是又不存在的父目录。
目录的遍历
  • public String[] list():返回一个String数组,表示该File目录中的所有的子目录或者子文件。
  • public File[] listFile():返回一个File数组,表示该File目录中的所有的子目录或者子文件。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值