Lambda
Lambda 表达式,也可称为闭包,Lambda 允许把函数作为一个方法的参数。
- 格式
(参数列表) -> {代码块}
(parameters) -> expression
或
(parameters) ->{ statements; }
- 前置条件
lambda表达式是一段执行某种功能的代码块,需要使用相应的对象接受,规定使用lambda表达式的前置条件是作为参数的对象必须是接口且接口有且仅有一个未被覆写的抽象方法。
- lambda表达式的作用在于实现简化部分接口实现类方法的过程,减少代码量
通过前置条件可以得出在接口只有一个抽象方法时直接用lambda表达式尤其方便,可以实现任意功能的函数。
public class LambdaTest {
public static void main(String[] args) {
int a=1,b =2;
//通过已知类访问
Sum sum = new Sum();
int sum1 = sum.sum(a, b);
//匿名内部类
new Sum().sum(a, b);
Delete del = (a1,b1)->{ return a1-b1;};
System.out.println(del.delete(b,a));
}
}
//抽象类
class Sum{
private int a;
private int b;
public int sum(int a,int b){
return a+b;
}
}
//接口
interface Delete{
public int delete(int a,int b);
}
通过上面案例可看出lambda表达式直接实现了减法的功能省去了接口的继承方法重写的步骤。
- 函数式接口
public interface LambdaFctory<T> {
//有返回值类型
T funcAny(T elem[]);
}
public class Test2{
public static void main(String[] args) {
LambdaFctory lambdaFctory = ( Object b[])->{ return (int)b[0]+(int)b[1];};
Object[] obj = new Object[] {1,2,3};
System.out.println(lambdaFctory.funcAny(obj));
}
}
public interface UnitFactory {
public void funcUnit(ArrayList list);
}
public class Test3 {
public static void main(String[] args) {
UnitFactory unitFactory = (ArrayList list) ->{
for (Object obj:list){
System.out.println(obj);
}
};
ArrayList list = new ArrayList(Arrays.asList(1,2,3,4,5,6));
unitFactory.funcUnit(list);
}
}
5. labmda作为函数函数参数
lambda作为参数传递,类型必须为接口,且满足使用lambda的前置条件。
如上图所示lambda返回值类型为一个接口。
public class Test5 {
public static void main(String[] args) {
//函数接口编程
LambdaT5 lambdaT5 = (String s) -> {
System.out.println(s);
};
//lambda参数传递
Abstract5 abstract5 =new Abstract5();
abstract5.AbstractPrint( (String s) -> System.out.println(s));
String str = "测试";
abstract5.AbstractPrint( (s) -> System.out.println(str));
}
}
interface LambdaT5{
void print(String s);
}
class Abstract5{
void AbstractPrint(LambdaT5 lambdaT5){
lambdaT5.print("抽象类调用了接口方法");
}
}
在上面案例中,抽象类的参数为函数接口,因此在使用抽象类是直接将lambda表达式作为参数传递。需要注意的是在labmda传递变量时,需要再抽象类中传递。
lambda表达式的重要特征:
- 首先类型必须是接口 interface
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
lambda学习站点
Stream
Java 8 API有一个新的抽象称为Stream——流
,用一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Java Stream是对集合做一些类似过滤、排序、对象转换之类的操作。 Java中的Stream并不会存储元素,而是按需计算,处理。
流的来源:可以是集合,数组,I/O channel, 产生器generator 等。
行动操作: 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
转化操作:将流转换为java集合。
JDK8
生成流
-
stream()
——为集合创建串行流。 -
parallelStream()
——为集合创建并行流。
流行动操作
Stream的集合操作有:filter, map, reduce, find, match, sorted等
记住Stream的主要功能,需要时查手册就可以了
JDK8中文开发手册
Java8中Stream详细用法大全
Java 8 Stream
Optional
Optional 类是一个可以为null的容器对象。Optional 是个容器,它可以保存类型T的值(一个值),或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。Optional 类的引入很好的解决空指针异常。
具体来说Optional是用来对java 对象判空用的,把一个对象存储到Optional中,Optional对象提供了众多方法对容器里的对象处理和判断,其判空功能减少java.lang.NullPointerException报错的出现。
进入Optional源码可以看到该对象使用final
关键字修饰
final修饰的对象不可更改,不能继承。Optional需要携带泛型
Optional<Object> empty = Optional.empty()
。
- 创建
如上图所示Optional对象提供了三种方法用来创建该对象:
(1) 使用静态方法 empty() 创建一个空的 Optional 对象;
(2) 使用静态方法 of() 创建一个非空的 Optional 对象;
(3) 使用静态方法 ofNullable() 创建一个即可空又可非空的 Optional 对象。
ofNullable() 方法内部有一个三元表达式,如果为参数为 null,则返回私有常量 EMPTY;否则使用 new 关键字创建了一个新的 Optional 对象.
- 使用
Optional提供了众多方法对其元素处理,更多方法请移步干货,一文彻底搞懂 Java 的 Optional
Optional API
Optional判空
@Test
public void method(){
String str = "hello Optional";
Optional<String> str1 = Optional.of(str);
//非空判断
boolean empty = str1.isEmpty();
System.out.println(empty);
//容器判断,空返回false,否则返回true
boolean present = str1.isPresent();
System.out.println(present);
}
Optional取值
@Test
public void method3(){
String str = "hello Optional";
Optional<String> container = Optional.of(str);
String s = container.get();
System.out.println(s);
}
时间处理
- 旧时间处理
java.util.Date
@Test
public void method1(){
Date date = new Date();
System.out.println(date);
}
/*
Tue Feb 28 16:00:28 CST 2023
*/
java.sql.Date
继承于java.util.Date
只用于记录当前时间
@Test
public void method2(){
long time = System.currentTimeMillis();
java.sql.Date date = new java.sql.Date(time);
System.out.println(date);
}
/*
2023-02-28
*/
默认的时间格式并不能满足日常的需要,需要用下面这两个类来转化格式
java.text.DateFormat;
java.text.SimpleDateFormat
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Test1 {
public static void main(String[] args) {
//初始格式
Date date1 = new Date();
System.out.println(date1);
//规范日期
DateFormat date = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.CHINA);
//规范时间
DateFormat time = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.CHINA);
//格式化日期
String str = date.format(date1);
//格式化时间
String str1 = time.format(date1);
String strdate = str+" "+str1;
System.out.println(strdate);
/*
Tue Feb 28 15:45:14 CST 2023
2023年2月28日 下午3:45:14
*/
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(dateFormat.format(new Date()));
}
}
SimpleDateFormat(String pattern)
:用指定的格式来返回时间字符,能自动识别下面的字符:
更多请看Java日期格式化(DateFormat类和SimpleDateFormat类)
- 新时间处理
新的时间包位于java.time
包涵盖了所有处理日期,时间,日期/时间,时区,时刻等操作。
Java对时间的处理
BASE64
Java8 Base64
一般用于图片存在数据库,建议直接存储在文件夹