java8与函数式编程

一、java8与函数式编程

1.Lambda表达式

Lambda表达式允许开发人员编写简洁的“计算片段”,并将他们传递给其他代码。接受代码可以选择再核实的时候来执行“计算片段”

Lambda表达式的格式:参数、箭头->、以及表达式

①如果负责计算的代码无法用一个表达式标识,可以用{}包括代码并明确使用return语句,例:

String[] strings = {"aa","aaaa","a","aaaa"}
/** 旧写法 **/
class LengthComparator implements Comparator<String> {
   @Overrite
   public int compare(String first,String second) {
       return Integer.compare(first.length(),second.length());
   }
}
Arrays.sort(strings,new LengthComparator());

/** 新写法 **/
Comparator<String> lengthComparator = (String first, String second) -> {
   //return Integer.compare(first.length(),second.length());
   if(first.length() < second.length()) return -1;
   else if(first.length() > second.length()) return 1;
   else return 0;
}
Arrays.sort(strings,lengthComparator);

②如果表达式没有参数,可以使用小括号代替,例:

Thread t = new Thread( () -> {
    for(i=1;i<10;i++) {
        System.out.println(i);
    }
})

③如果一个lambda表达式的参数类型是可以被推导的,那么可以省略他们的类型,例:

Comparator<String> lengthComparator = (first, second) -> return Integer.compare(first.length(),second.length());

对于只包含一个抽象方法的接口,你可以通过lambda表达式来创建该接口的对象,这种接口被称为函数式接口。即函数式接口只能包含一个抽象方法,因为java8中接口可以声明非抽象的方法。

方法引用

三种方式:

​ 对象::实例方法

​ 类::静态方法

​ 类::实例方法

	@Test
	public void demo1() {
		//方法引用
		Thread myThread = new Thread(System.out::println);
		myThread.run();
		
		class Greeter{
			public void greet() {
				System.out.println("方法引用");
			}
		}
		
		class ConcurrentGeeter extends Greeter {
			
			public void greet() {
				Thread greetThread = new Thread(super::greet);
				greetThread.start();
			}
		}
		Greeter greeter = new ConcurrentGeeter();
		
		greeter.greet();
	}

构造器引用

与方法引用类似,不同的是在构造器引用中方法名是new。

	public void demo2() {
		List<String> labels = new ArrayList<>();
		
		Stream<Button> stream = labels.stream().map(Button::new);
		List<Button> buttons = stream.collect(Collectors.toList());
		
	}

变量作用域

lambda表达式的方法体与嵌套代码块有着相同的作用域,因此也适用同样的命名冲突和屏蔽规则。在lambda表达式中不允许声明一个与局部变量同名的参数或者局部变量。

默认方法

静态方法

2.Stream api

一个stream表面上看与一个集合很类似,允许你改变和获取数据,但实际上它与集合有很大的区别:

​ stream自己不会存储元素;

​ stream操作不会改变源对象;

​ stream操作符可能是延时执行的,意味着他们会等到需要结果的时候才执行。

stream转换 filter,map,flatMap

filter方法

filter:产生一个新的流,其中包含符合某个特定条件的所有元素

public void demo3() {
		List<String> wordList = Arrays.asList(new String[]{"a","b","c","cc"});
		Stream<String> words = wordList.stream();
		
		//流只能使用一次,此处打印的话下面就不能使用了
		System.out.println(words.count());
		
		Stream<String> longWords = words.filter(w->w.length()>1);
		System.out.println(longWords.count());
	}

map方法

map:对一个流中的值进行某种形势的转换,将源stream中的元素传递给一个执行转换的函数Function<? super T,? extends T>,返回转换后的stream

	public void demo4() {
		List<String> wordList = Arrays.asList(new String[]{"a","b","c","cc"});
		Stream<String> words = wordList.stream();
		
		//流只能使用一次,此处打印的话下面就不能使用了
		//System.out.println(words.count());
		Stream<String> longWords = words.map(String::toUpperCase);
		System.out.println(longWords.collect(Collectors.toList()).toString());
	}

flatMap方法

flatMap:monads理论实现,将多个函数结果展开。个人理解就是递归调用或者链式调用,获取最小单位

	public void demo6() {
		List<String> wordList = Arrays.asList(new String[]{"aaa","bbb","cccc","ddd"});
		
		//Stream<Stream<Character>> result = wordList.stream().map(LambdaTest::characterStream);
		//System.out.println(result.collect(Collectors.toList()));
		
		Stream<Character> result = wordList.stream().flatMap(LambdaTest::characterStream);
		System.out.println(result.collect(Collectors.toList()));
		
	}
	
	public static Stream<Character> characterStream(String s) {
		List<Character> result = new ArrayList<>();
		for (char c : s.toCharArray()) {
			result.add(c);
		}
		return result.stream();
	}

limit方法

limit(n):返回一个包含n个元素的新流。这个方法适用于裁剪制定长度的流。

public void demo7() {
		//产生100个随机数字
		Stream<Double> randoms = Stream.generate(Math::random).limit(100);
		System.out.println(randoms.collect(Collectors.toList()));
		
		List<String> wordList = Arrays.asList(new String[]{"aaa","bbb","cccc","ddd"});
		Stream<String> wordLimit = wordList.stream().limit(2);
		System.out.println(wordLimit.collect(Collectors.toList()));
		
	}

skip方法

skip(n):丢弃掉前面n个元素。

	public void demo8() {
		
		List<String> wordList = Arrays.asList(new String[]{"aaa","bbb","cccc","ddd"});
		Stream<String> wordLimit = wordList.stream().skip(2);
		System.out.println(wordLimit.collect(Collectors.toList()));
		
	}

concat方法

concat(Stream a,Stream b):将两个流连接合并为一个流

	public void demo9() {
		
		List<String> wordList1 = Arrays.asList(new String[]{"aaa","bbb","cccc","ddd"});
		List<String> wordList2 = Arrays.asList(new String[]{"1","2","3","4"});
		Stream<String> concat = Stream.concat(wordList1.stream(), wordList2.stream());
		System.out.println(concat.collect(Collectors.toList()));
		//打印结果:[aaa, bbb, cccc, ddd, 1, 2, 3, 4]
	}

distinct方法

distinct():根据原始流中的元素,返回一个具有相同顺序并剔除了重复元素的新流。

	public void demo10() {
		
		List<String> wordList = Arrays.asList(new String[]{"aaa","bbb","aaa","bbb","ccc","ddd","bbb","aaa",});
		Stream<String> distinct = wordList.stream().distinct();
		System.out.println(distinct.collect(Collectors.toList()));
		//打印结果:[aaa, bbb, ccc, ddd]
	}

sort方法

sorted():实现了Comparable接口

	public void demo11() {
		
		List<Integer> wordList = Arrays.asList(new Integer[]{1,4,2,2,6,3,7,4});
		Stream<Integer> sorted = wordList.stream().sorted();
		System.out.println(sorted.collect(Collectors.toList()));
		//打印结果:[1, 2, 2, 3, 4, 4, 6, 7]
	}

sorted(比较器):参数为一个Comparator对象

	public void demo12() {
		
		List<String> wordList = Arrays.asList(new String[]{"aa","bbb","a","bb","cc","dd","b","aaa",});
		Stream<String> sorted = wordList.stream().sorted((first,second) -> Integer.compare(first.length(), second.length()));
		System.out.println(sorted.collect(Collectors.toList()));
		//打印结果:[a, b, aa, bb, cc, dd, bbb, aaa]
	}

max

返回Stream中的最大值。

返回对象为:Optional

min

返回stream中的最小值

返回对象为:Optional

fildFirst

返回非空集合中的第一个值,通常与filter方法结合使用。

findAny

找到任意的一个匹配的元素,这个方法在对stream进行并行执行时十分有效,因为只要再任何片段中发现了第一个匹配元素,就会结束整个计算。

anyMatch

流中是否含有匹配元素

allMatch

所有元素都匹配

noneMatch

没有元素匹配

reduce

如果你希望对元素求和,或者以其他方式将流中的元素组合为一个值,你可以使用reduce方法。

	public void demo13() {
		
		List<Integer> wordList = Arrays.asList(new Integer[]{1,4,2,2,6,3,7,4});
		Optional<Integer> reduce = wordList.stream().reduce((x,y) -> x + y);
		System.out.println(reduce.get());
		//打印结果:29
	}

	public void demo13() {
		
		List<String> wordList = Arrays.asList(new String[]{"aa","bbb","a","bb","cc","dd","b","aaa",});
		Optional<String> reduce = wordList.stream().reduce((x,y) -> x + y);
		System.out.println(reduce.get());
		//打印结果:aabbbabbccddbaaa
	}

collect

前面已经有应用

Collectors.joining()的用法:

将流中所有字符串连接收集起来

	public void demo14() {
		
		List<String> wordList = Arrays.asList(new String[]{"aa","bbb","a","bb","cc","dd","b","aaa",});
		String collect = wordList.stream().collect(Collectors.joining());
		System.out.println(collect);
		//打印结果:aabbbabbccddbaaa
	}

Collectors.joining(分隔符)的用法:

将流中所有字符串连接收集起来并再中间添加分隔符

	public void demo15() {
		
		List<String> wordList = Arrays.asList(new String[]{"aa","bbb","a","bb","cc","dd","b","aaa",});
		String collect = wordList.stream().collect(Collectors.joining("|"));
		System.out.println(collect);
		//打印结果:aa|bbb|a|bb|cc|dd|b|aaa
	}

Collectors.summarizing

将Stream结果聚合为一个总和,平均值、最大值、最小值。

	public void demo16() {
		
		List<String> wordList = Arrays.asList(new String[]{"aa","bbb","a","bb","cc","dd","b","aaa",});
		IntSummaryStatistics collect = wordList.stream().collect(Collectors.summarizingInt(String::length));
		System.out.println("元素长度平均值:" + collect.getAverage());
		System.out.println("数量:" + collect.getCount());
		System.out.println("长度最大是:" + collect.getMax());
		System.out.println("长度最小是:" + collect.getMin());
		System.out.println("所有元素长度求和:" + collect.getSum());
		/**打印结果:
		元素长度平均值:2.0
        数量:8
        长度最大是:3
        长度最小是:1
        所有元素长度求和:16
		**/
	}

3.javaFX

4.新的日期事件API

Instant

表示时间轴上的一个点

Duration

表示两个瞬时点之间的时间量

	public void demo1() throws Exception {
		// 计算两个瞬时点之间的时间距离
		Instant now1 = Instant.now();
		System.out.println(now1);//打印:2022-06-10T10:08:05.622685500Z
		//?疑似带时区,执行时间为下午18:08:05.622685500Z
		TimeUnit.SECONDS.sleep(5);
		
		Instant now2 = Instant.now();
		
		Duration between = Duration.between(now1, now2);
		
		System.out.println(between.toMillis());//打印:5030
	}

LocalDate

LocalDate是一个带有年份/月份/当月天数的日期。可以使用now或者of创建。

	public void demo2() {
		LocalDate now = LocalDate.now();
		System.out.println(now);//2022-06-10
		LocalDate birthday = LocalDate.of(1992, 5, 21);
		System.out.println(birthday);//1992-05-21
        LocalDate birthday2 = LocalDate.of(92, 5, 21);
		System.out.println(birthday2);//0092-05-21
        int dayOfMonth = now.getDayOfMonth();
		System.out.println(dayOfMonth);//10
		int dayOfYear = now.getDayOfYear();
		System.out.println(dayOfYear);//161
		DayOfWeek dayOfWeek = now.getDayOfWeek();
		System.out.println(dayOfWeek);//FRIDAY
		Month month = now.getMonth();
		System.out.println(month);//JUNE
		int monthValue = now.getMonthValue();
		System.out.println(monthValue);//6
	}

5.并发增强

6.Nashorn

内置的高质量的JavaScript引擎,可以在JVM上执行JavaScript,并且与Java代码进行交互操作。

7.其他改进

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值