day02-java8新特性

Lambda表达式

在开始java8新特性前,回顾一下上周学过的lambda表达式。
多线程那块也比较薄弱;
格式
-> lambda操作符
左边:形参列表
右边:lambda体,(重写的抽象方法的方法体)
总结:左边,如果lambda形参列表只有一个参数,()可以省略。
右边,如果只有一条执行语句,省略这对{}和return关键字。

因为感觉理解深度不够,去看了原视频
下面这个例子,com2用了常规的lambda,com3使用了方法引用对2的结果进行进一步的优化。

@Test
	public void test2(){
		Comparator<Integer> com1=new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return Integer.compare(o1,o2);
			}
		};

		int compare1 = com1.compare(12, 21);
		System.out.println(compare1);
		System.out.println("***********");

		Comparator<Integer> com2=(o1,o2)->Integer.compare(01,02);

		int compare2=com2.compare(32,12);
		System.out.println(compare2);
		System.out.println("******");

		Comparator<Integer> com3=Integer:: compare;
		int compare3=com3.compare(32,12);
		System.out.println(compare3);
		};

函数式接口

接口中之声明了一个抽象方法,称为函数式接口。
@FunctiionalInterface注解
lambda表达式本质:作为函数式接口的实例。

当需要对一个函数式接口实例化时,可以使用lambda表达式。

java内置四大核心函数式接口
Consumer 消费型接口 void accept(T t){}
Supplier 供给型接口 T get()
Function<T,R> R apply(T t)
Predicate 断定型接口 boolean test(T t) 用来确定类型为T的对象是否满足某约束,返回boolean值
举例:要有抽象的能力

public class LambdaTest2 {

	@Test
	public void test1(){
		List<String> list= Arrays.asList("北京","dongjing","xijing","wangjing");
		List<String> filterStrs = filterString(list, new Predicate<String>() {
			@Override
			public boolean test(String s) {
				return s.contains("jing");
			}
		});

		System.out.println(filterStrs);
		System.out.println("***********");
		List<String> filterStrs1 = filterString(list,s->s.contains("jing"));
		System.out.println(filterStrs1);

	}

	//根据给定的规则,过滤集合中的字符串。此规则有predicate的方法决定
	public List<String> filterString(List<String> list, Predicate<String> pre){
		ArrayList<String> filterList = new ArrayList<>();

		for(String s:list){
			if(pre.test(s)){
				filterList.add(s);
			}
		}
		return filterList;
	}
}

Stream API

对数据的运算 与cpu打交道
集合关注数据存储
类似于数据库中对表的操作
jdbc底层原理:一套有接口的api 可以操作数据库

  • 注意点:
    1、Stream自己不会存储对象
    2、不会改变源对象
    3、操作时延迟执行

  • 使用流程
    实例化
    中间操作
    终止操作

  • 注意点
    一个中间操作连,对数据源数据进行处理
    一旦执行终止操作,执行中间操作链,并产生结果,之后,不再被使用。

  • 步骤1、Stream实例化

public class StreamAPITest {
	@Test
	public void test1(){

		//创建Stream方式一:通过集合获取
		List<Employee> employees = EmployeeData.getEmployees();
		//返回一个顺序流
		Stream<Employee> stream = employees.stream();
		//并行流
		Stream<Employee> parallelStream = employees.parallelStream();
	}

	//创建Stream方式二:通过数组
	@Test
	public void test2(){
		int[] arr=new int[]{1,2,3,4,5,6};
		//arrays类中静态方法
		IntStream stream = Arrays.stream(arr);

		Employee e1=new Employee(1001,123);
		Employee e2=new Employee(1002,123);
		Employee[] arr1=new Employee[]{e1,e2};

		Stream<Employee> stream1 = Arrays.stream(arr1);
	}
	
	//方式三:通过stream的of方法
	@Test
	public void test3(){
		Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
	}
}

-中间操作
筛选与切片

public class StreamAPITest1 {
	@Test
	public void test1(){
		List<Employee> list = EmployeeData.getEmployees();
		Stream<Employee> stream = list.stream();
		//查询员工表中薪资大于7000员工信息
		stream.filter(e->e.getAge()>10).forEach(System.out::println);

		System.out.println();
		//limit(n)-截断流  重新生成stream
		list.stream().limit(3).forEach(System.out::println);

		System.out.println();
		//skip 跳过元素
		list.stream().skip(3).forEach(System.out::println);
	}
}

映射
map(Function f):接收一个函数作为参数,将元素转为其他形式或提取信息

@Test
	public void test2(){
		List<String> list = Arrays.asList("aa", "dd", "cc");
		list.stream().map(str->str.toUpperCase()).forEach(System.out::println);
	}

映射后面有个flatmap 跳过了

排序

@Test
	public void test3(){
		List<Integer> list = Arrays.asList(1, 3, 2, 4, 2, 5, 2);
		list.stream().sorted().forEach(System.out::println);

		List<Employee> employees = EmployeeData.getEmployees();
		employees.stream().sorted((e1,e2)->{
			return Integer.compare(e1.getAge(),e2.getAge());
		}).forEach(System.out::println);
	}

-终止操作

  • 匹配与查找
@Test
	public void test1(){
		List<Employee> employees = EmployeeData.getEmployees();

		boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 18);
		System.out.println(allMatch);
	}

规约
reduce(T identity,BinaryOperator):可以将流中元素反复结合,得到一个值。

收集 将流转为其他形式

Option类的使用

容器 可以保存类型T的值,代表值存在。
避免空指针异常
Optional类
为了解决java中空指针问题
go语言 java的运行效率
scalar
python写的快 不用关注运行效率

  • 常用方法
public class OptionalTest {

	@Test
	public void test1(){
		Optional<Object> op1=Optional.empty();
		if(op1.isPresent()){
			System.out.println("数据为空");

		}
		//System.out.println(op1.get());
		System.out.println(op1);
		System.out.println(op1.isPresent());
	}

	@Test
	public void test2(){
		String str2="hello";
		//封装数据,要求对象不能为空
		Optional<String> op1 = Optional.of(str2);

		//get方法通常和of方法搭配使用,用于获取内部封装数据。
		String s = op1.get();
		System.out.println(s);
	}

	@Test
	public void test3(){
		//String str="jei";
		String str=null;
		//封装数据t赋值给optional内部value
		Optional<String> op1 = Optional.ofNullable(str);
		//orElse(T t1):如果内部value非空,返回此value值
		String str2 = op1.orElse("shangha");
		System.out.println(str2);
	}
}

lambda表达式是一个函数式接口实例。
lambda表达式是一个函数式接口实例
lambda表达式是一个函数式接口实例。

方法引用

使用情景:当要传递给lambda体的操作,已经有实现的方法,可以使用方法引用。
它也是lambda表达式,可以看成是语法糖
你看一下,Consumer中的void accept(T t)
和 PrintStream中的void println(T t) 结构一致,所以下面的东西可以做如此修改

  • 情况一:
Consumer<String> con1=str->System.out.println(str);

等价于

PrintStream ps=System.out;
Consumer<String> con2=ps::println;

需要判断使用类或者对象,方法是不是静态的。

例子2、

Employee emp=new Employee(id:1001,name:"Tom");
Supplies<String> sup1=()->emp.getName();

等价于

Supplies<String> sup2=emp::getName;
  • 情况二
    类::静态变量
    //Comparator中的int compare(T t1,T t2)
    //Integer中的int compare(T t1,T t2)
    eg1:
Comparator<Integer> com1=(t1,t2)->Integer.compare(t1,t2);

等价于

Comparator<Integer> com2=Integer::compare;

//这个也简单好理解
eg2

Function<Double,Long> func1=d->Math.round(d);
//等价于
Function<Double,Long> func2=Math::round;
  • 情况三 类::实例方法
    //Comparator中的int compare(T t1,T t2)
    //String中的int t1.compareTo(t2)
    eg1:
Comparator<String> com1=(s1,s2)->compareTo(s2);
等价与
Comparator<String> com1=String::compareTo;
//两个参数时,如果第一个方法作为调用者出现,也存在引用,但是是用类

eg2

BiPredicate<String,String> pre1=(s1,s2)->s1.equals(s2);
//等价于
BiPredicate<String,String> pre2=**String**::equals;

eg3:

Function<Employee,String> func1=e->e.getName();
//等价于
Function<Employee,String> func2=Employee::getName;

//就上面三种,重要的就是判断条件,做出选择

构造器引用

//Supplier中的T get()
//Employee的空参构造器:Employee()
原始构造器写法
eg1:

Supplier<Employee> sup=new Supplier<Employee>(){
	public Employee get(){
		return new Employee();
	}
}
Supplier<Employee> sup1=()->new Employee();
//等价于
Supplier<Employee> sup2=Employee::new;

eg2:

Function<Integer,Employee> func1=new Employee(id);
//等价于
Function<Integer,Employee> func2=Employee::new;

总结:构造器引用和方法引用类似

数组引用

把数组看成类类型。
数组类型[] ::new

Function<Integer,Integer[]> fun=(n)->new Integer[n];

等同于

Function<Integer,Integer[]> fun=Integer[]::new;

e2:

Function<Integer,String[]> func1=length->new String[length];
//等同于
Function<Integer,String[]> func2=String[]::new;

java8新特性(csdn文章)

循环遍历
前:

for(User user :users){
	sout(user.toString());
}

现在:

users.foreaach(o->sout(o.toString()));

2、函数式编程:匿名内部类
before:

new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("hello world");
			}
		}).start();

after:

new Thread(() -> System.out.println("hello world")).start();

3、排序(升序)
before:

Collections.sort(userList,new Comparator<User>()){
	@Override
	public int compare(User o1,User o2){
		return o1.getAge()-o2.getAge();
	}
}

注意一下,数值比较可以直接相减排序;如果是非数值比较,应当使用compareTo()方法

return o1.getName().compareTo(o2.getName());

after1:

Colletions.sort(userList,(01,02)->o1.getAge()-o2.getAge());

after2:

在这里插入代码片

5、过滤

文件流操作(复习)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值