饭后来学学jdk1.8的特性吧

在jdk1.8版本之前,我们操作一些数据,会让人感觉很繁琐,我们明明只要判断一个内容,如果存在,则输出,这明显可以一句代码完成啊,可是,在java1.8版本之前,我们必须使用一个循环来搞定,自从jdk1.8面世以来,给我们带来了好多特性,但是好多人还沉浸在jdk1.6+中,emmm,时代在发展,也不能停止学习。

一、lambda表达式

什么是lambad?lambad就是允许把函数作为一个方法的参数。

其中lambad就是允许把函数作为一个方法的参数,这句话怎么理解呢?学过javaScript的同学一定不会陌生,因为我们可以直接在函数中传递函数。
eg:

	function test(callback){
		console.log('hello javaScript')
		callback()
	}
	function run(){
		test(()=>{
		console.log('我只是callback的内容')
	})
	}
	run()

在这里插入图片描述

1.1 labmda操作循环

我们可以清晰的看出来,在javaScript语言我们可以足够将函数作为参数传入方法。在jdk1.8之前,java开发者根本不可能达到类似的效果。
在java1.8之前,我们想要输出一个列表的内容,我们可以使用for循环:

	List<String> list = new ArrayList();
	list.add("raven");
	list.add("hello world");
	list.add("123");
	for (String s:list){
	    System.out.println(s);
	}

而升级到jdk1.8之后,我们可以直接使用lambda表达式,如下:

	 List<String> list = new ArrayList();
	 list.add("raven");
	 list.add("hello world");
	 list.add("123");
	 //可选的类型声明
	 list.forEach((e)-> {
	 	System.out.println(e)
	 });
	  //可选的大括号
	 list.forEach((String e)-> System.out.println(e));
	 //可选的小括号
	 list.forEach(e->{
	 	System.out.println(e)
	 });

其中需注意:

  • 可选类型声明:也就是说上面的对象e不用你声明,编译器可以识别
  • 可选的参数圆括号:也就是当lambda表达式只有一个参数的时候,括号可要可不要,如果有多个参数的话,那么必须加括号包住参数
  • 可选的大括号:如果lambda表达式里面只有一句代码,那么不必要加外面的大括号
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

1.1 labmda创建线程

之前我们创建线程可以如下:

// 普通方法创建线程
 new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("普通的创建线程方法");
            }
        }).start();
// 匿名类创建线程
 new Thread(){
            @Override
            public void run() {
                System.out.println("匿名类创建线程");
            }
        }.start();

而使用了lambda创建线程,就更简洁了:如下:

new Thread(()->{
           System.out.println("我是lambda方法创建的线程");
       }).start();

那么为什么我们可以这么做呢?因为Runnable接口中,如下图:
在这里插入图片描述
在这里插入图片描述
首先在Thread方法中,有唯一一个含参(Runnable)的方法,而Runnable只有 一个公共无参方法,所以编译器当然可以自动识别到你写的lambda方法所对应要适配方法是哪个方法。
所以我们平时调用一个方法的时候,如果该参数是一个接口类型的参数,那么我们就可以使用lambda表达式去简化开发。

二、stream流式特性

2.1 filter(过滤)

这种过滤不要太简单了。像之前的话还得写个for循环判断才能拿到数据,而使用Stream特性一句代码搞定!

扫描二维码关注公众号,回复: 10648862 查看本文章
	List<String> list = new ArrayList();
	list.add("raven");
	list.add("hello world");
	list.add("hello java");
	list.add("hello python");
	List<String> collect = list.stream().filter(e -> e.contains("hello")).collect(Collectors.toList());

2.2 sorted(排序)

有时候我们还需要list排序。

    List<String> list = new ArrayList();
    list.add("4");
    list.add("1");
    list.add("3");
    list.add("2");
    List<String> sorted = list.stream().
    sorted().collect(Collectors.toList());
    //按自然输入排序后 输出 [1, 2, 3, 4]
   System.out.println(sorted);

当然这只是String对象,如果是其他对象该怎么按照自定义属性怎么排序呢?

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	list.add(new User(6));
	list.add(new User(6));
	// 方法1 自定义比较器
	List<User> collect = list.stream().sorted(
	 (o1, o2) ->  o1.getId()-o2.getId() )
			.collect(Collectors.toList()
	);
	collect.forEach(e-> System.out.println(e));
	  // 方法2 推荐使用comparing 方法
	List<User> collect2 = list.stream().sorted(Comparator.comparing(User::getId)).collect(Collectors.toList());
	collect2.forEach(e-> System.out.println(e));
	// 逆序
	List<User> collect3 = list.stream().sorted(Comparator.comparing(User::getId).reversed()).collect(Collectors.toList());
	collect3.forEach(e-> System.out.println(e));

如上代码就可以让List的数据按照我们自定义的id属性进行排序啦,当然我们也可以直接使用List自带的sort方法排序。如:

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	//方法1
	list.sort((o1, o2) ->  o1.getId()-o2.getId() );
	list.forEach(e-> System.out.println(e));
	//方法2 推荐使用Comparator.comparing方法
	list.sort(Comparator.comparing(User::getId));
	list.forEach(e-> System.out.println(e));

另外如果我们的User对象如果实现了比较器,直接用即可:

	public class User implements Comparable{
		private int id;
		public User(int id) {
			this.id = id;
		}
		@Override
		public int compareTo(Object o) {
			if(this.getId() > ((User)o).getId()){
				return 1;
			}else if(this.getId() == ((User)o).getId()){
				return 0;
			}else{
				return -1;
			}
	
		}
	}
	
	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	list.add(new User(6));
	list.add(new User(6));
	List<User> sorted = list.stream().sorted().collect(Collectors.toList());;
	sorted.forEach(e-> System.out.println(e));

2.3 limit

返回前n个元素的流,下面这段代码,返回查询到的数据的前两个

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	list.add(new User(6));
	list.add(new User(6));
	List<User> collect = list.stream().filter(e -> e.getId() > 10).limit(2).collect(Collectors.toList());
	collect.forEach(e-> System.out.println(e));
// 输出
//User{id=227}
//User{id=12}

2.3 skip

跳过n个元素后输出
首先过滤id>6的的数据,再从过滤后的数据的第二个数据开始输出

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	list.add(new User(6));
	list.add(new User(6));
	List<User> collect = list.stream().filter(e -> e.getId() > 5).skip(2).collect(Collectors.toList());
	collect.forEach(e-> System.out.println(e));
	// 输出
	//User{id=12}
	//User{id=227}

2.4 map

可将查到的列表里提取其中的一个属性作为新的列表 ,以下我提取了user的id属性。

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	List<Integer> collect = list.stream().map(User::getId).collect(Collectors.toList());
	collect.forEach(e-> System.out.println(e));

2.5 flatMap

flatMap与map的区别在于 flatMap是将一个流中的每个值都转成一个个流。

	List<List<String>> type = new ArrayList<>();
	List<String> person = new ArrayList<>();
	person.add("高智商");
	person.add("会说话");
	
	List<String> dog = new ArrayList<>();
	dog.add("低智商");
	dog.add("会汪汪汪");
	
	type.add(person);
	type.add(dog);
	//flatMap(Collection::stream)
	List<String> collect = type.stream().flatMap(e->{
	    String s = String.join(",",e);
	    return Stream.of(s);
	}).collect(Collectors.toList());
	//输出
	//高智商,会说话
	//低智商,会汪汪汪
	collect.forEach(e-> System.out.println(e));

下面的代码先通过map把数组转换成了字符串数组的数组,如
[ [“H”,“e”,“l”,“l”,“o”],[“W”,“o”,“r”,“l”,“d”] ],然后再用flatMap方法把大数组里面的两个数组都转换成流处理,得到[H, e, l, l, o, W, o, r, l, d] ,然后去重,最后转变成数组。

	 String[] strings = {"Hello", "World"};
	List collect = Arrays.asList(strings).stream().
	map(s -> s.split("")).flatMap(Arrays::stream)
	.distinct().collect(Collectors.toList());
	System.out.println(collect);
	//输出 [H, e, l, o, W, r, d]

2.6 allMatch

检测里面的数据是否都满足条件.
显而易见,所有的id都>=10,应该输出true

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	boolean flag = list.stream().allMatch(e -> e.getId() >= 10);
	System.out.println(flag);

2.7 anyMatch

若存在满足条件的则就为true

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	boolean flag = list.stream().anyMatch(e -> e.getId()>200);
	System.out.println(flag);

2.8 noneMatch

判断查询结果是否为空,如果为空,则为true

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	boolean flag = list.stream().noneMatch(e -> e.getId()>200);
	System.out.println(flag);

2.9 reduce

可以用来对数据的一些操作。

	List<User> list = new ArrayList();
	list.add(new User(227));
	list.add(new User(10));
	list.add(new User(12));
	list.add(new User(127));
	// 求id总和
	list.stream().map(User::getId).reduce((i,j)-> i+j).ifPresent(System.out::println);
	//id最大值
	list.stream().map(User::getId).reduce(Integer::max).ifPresent(System.out::println);
	//id最小值
	list.stream().map(User::getId).reduce(Integer::min).ifPresent(System.out::println);

2.99 collect

	List<User> list = new ArrayList();
	list.add(new User(227,"谢霆锋"));
	list.add(new User(10,"陈冠希"));
	list.add(new User(12,"余文乐"));
	list.add(new User(127,"吴彦祖"));
	
	// 输出总个数、总和、最小值、平均值、最大值
	IntSummaryStatistics summaryStatistics = list.stream().collect(Collectors.summarizingInt(User::getId));
	System.out.println(summaryStatistics);
	String str = list.stream().map(u -> u.getUserName()).collect(Collectors.joining("的朋友"));
	// 用‘的朋友’连接所有名字 故输出 谢霆锋的朋友陈冠希的朋友余文乐的朋友吴彦祖的朋友陈冠希
	System.out.println(str);
	// 用姓名做key,值为姓名分组的列表
	Map<String, List<User>> collect = list.stream().collect(Collectors.groupingBy(User::getUserName));
	System.out.println(collect);
	// 将陈冠希分一组,其他的分一组
	Map<Boolean, List<User>> collect2 = list.stream().collect(Collectors.partitioningBy(u->u.getUserName().equals("陈冠希")));
	System.out.println(collect2);

总结

关于java1.8 的特性还是挺多的,虽然不能面面俱到,但是每次回首也固然有收获。

发布了67 篇原创文章 · 获赞 359 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/huijiaaa1/article/details/105347744
今日推荐