栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

day02-java8新特性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

day02-java8新特性

Lambda表达式

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

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

@Test
	public void test2(){
		Comparator com1=new Comparator() {
			@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 com2=(o1,o2)->Integer.compare(01,02);

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

		Comparator 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 R apply(T t)
Predicate 断定型接口 boolean test(T t) 用来确定类型为T的对象是否满足某约束,返回boolean值
举例:要有抽象的能力

public class LambdaTest2 {

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

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

	}

	//根据给定的规则,过滤集合中的字符串。此规则有predicate的方法决定
	public List filterString(List list, Predicate pre){
		ArrayList 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 employees = EmployeeData.getEmployees();
		//返回一个顺序流
		Stream stream = employees.stream();
		//并行流
		Stream 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 stream1 = Arrays.stream(arr1);
	}
	
	//方式三:通过stream的of方法
	@Test
	public void test3(){
		Stream stream = Stream.of(1, 2, 3, 4, 5);
	}
}

-中间操作
筛选与切片

public class StreamAPITest1 {
	@Test
	public void test1(){
		List list = EmployeeData.getEmployees();
		Stream 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 list = Arrays.asList("aa", "dd", "cc");
		list.stream().map(str->str.toUpperCase()).forEach(System.out::println);
	}

映射后面有个flatmap 跳过了

排序

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

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

-终止操作

  • 匹配与查找
@Test
	public void test1(){
		List 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 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 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 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 con1=str->System.out.println(str);

等价于

PrintStream ps=System.out;
Consumer con2=ps::println;

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

例子2、

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

等价于

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

等价于

Comparator com2=Integer::compare;

//这个也简单好理解
eg2

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

eg2

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

eg3:

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

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

构造器引用

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

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

eg2:

Function func1=new Employee(id);
//等价于
Function func2=Employee::new;

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

数组引用

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

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

等同于

Function fun=Integer[]::new;

e2:

Function func1=length->new String[length];
//等同于
Function 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()){
	@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、过滤

文件流操作(复习)
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号