java8的新特性

				
Java8的新特性

	1)Lambda表达式

		概念:java8中增加了一个新的语法--Lambda表达式,并且引入了一个新的操作符(Lambda操作符): -> 
		
		Lambda操作符 -> :
			  -> 将Lambda表达式分为两个部分:
				左侧:指定了Lambda表达式需要的参数,参数的数据类型可以由编译器的“类型推断”机制推断得出,故可以省略。
				右侧:指定了Lambda表达式的方法体,即Lambda表达式要执行的功能。
		
		语法格式:
			
			格式一:无参数,无返回值
					() -> System.out.println("Hello Lambda!");

			格式二:有一个参数,并且无返回值
					(x) -> System.out.println(x)

			格式三:若只有一个参数,小括号可以省略不写
					x -> System.out.println(x)

			格式四:有两个以上的参数,有返回值,并且 Lambda 体中有多条语句
					(x, y) -> {
						System.out.println("函数式接口");
						return Integer.compare(x, y);
					};

			格式五:若 Lambda 体中只有一条语句, return 和 大括号都可以省略不写
					(x, y) -> Integer.compare(x, y);

			格式六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
					(Integer x, Integer y) -> Integer.compare(x, y);			
					
					

	2)函数式接口

		概念:只有一个抽象方法(默认方法与静态方法除外)的接口,称为函数式接口!
		
		补充:java8中,接口里可以有default方法(默认方法)和static方法(静态方法),实现类默认会继承defaul方法和static方法。
		
		声明一个函数式接口:
		
			@FunctionalInterface
			public interface FirstInterface {
				void run();
			}
		
		说明:
			1)可以通过Lambda表达式来创建函数式接口的对象。
			2)可以在函数式接口上使用@FunctionalInterface注解,这样我们就可以根据该注解来判断这个接口是否是一个函数式接口。
			3)Java8内置的四个核心函数式接口
					函数式接口				参数类型	返回类型	抽象方法			用途
				消费型接口:Consumer<T>			T		void		void accept(T t)	对类型为T的对象执行某一操作。
				供给型接口:Supplier<T>			无		T			T get()				返回类型为T的对象。
				函数型接口:Function<T, R>		T		R			R apply(T t)		对类型为T的对象执行某一操作,并返回R类型的结果。
				断言型接口:Predicate<T>		T		boolean		boolean test(T t)	确定类型为T的对象是否满足某约束,并返回boolean值。
				
				eg:
					// 对String类型的对象执行Lambda表达式(x -> System.out.println(x))的方法体。
					Consumer<String> strConsumer = x -> System.out.println(x);		// 创建一个Consumer(消费型接口)的对象
					strConsumer.accept("Consumer的accept方法!");					// 执行
				
					FirstInterface firstObj = () -> System.out.println("Hello Lambda!");
					firstObj.run();
				
		
	3)方法引用

		方法引用:
			说明:
				1)若Lambda方法体中的功能,已经有方法提供了实现,则可以使用方法引用。
				2)使用操作符 :: 将方法名和对象或类的名字分隔开来。
				
			格式:
			  对象名 :: 实例方法名
			  类名   :: 静态方法名
			  类名   :: 实例方法名
			eg:
				Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
				Comparator<Integer> com2 = Integer::compare;
		
		构造器引用
			格式: 类名 :: new
			eg:
				Supplier<Student> sup1 = () -> new Student();
				Supplier<Student> sup2 = Student::new;
			
		数组引用
			格式: type[] :: new
			eg:
				Function<Integer, String[]> fun1 = (args) -> new String[args];
				Function<Integer, String[]> fun2 = String[]::new;

				
	4)Stream API
	
	概念:Stream用于操作集合、数组等元素序列。
	
	Stream API 的操作步骤

		1)创建Stream
		
			创建Stream的方式:
				1>通过Collection中的 stream() 或 parallelStream() 来创建一个Stream
					eg:
						List<String> list = new ArrayList<>();
						Stream<String> stream = list.stream(); 					//获取一个顺序流
						Stream<String> parallelStream = list.parallelStream(); 	//获取一个并行流
					
				2>通过Arrays中的stream(T[] array)创建一个Stream
				3>通过Stream中的
					of(T... values)									创建一个Stream
					generate(Supplier<T> s)							创建一个无限Stream
					iterate(final T seed, final UnaryOperator<T> f)	创建一个无限Stream
					

		2)Stream的中间操作
		
			Stream<T> filter(Predicate<? super T> predicate)	选择满足条件的元素,将不满足条件的元素过滤掉。
			Stream<T> limit(long n);							将流截断,只保留流中的前n个元素
			Stream<T> skip(long n);								将流中的前n个元素剔除掉
			Stream<T> distinct();								将流中的元素进行去重操作。根据元素的hashCode()方法和equals()方法来确定唯一性。
			
			Stream<T> sorted();									将流中的元素进行自然排序
			Stream<T> sorted(Comparator<? super T> comparator); 将流中的元素按照指定的规则排序
				举例:
				1>按照Obj的id升序排序:objList.stream().sorted(Comparator.comparing(Obj::getId)).collect(Collectors.toList());
			
			<R> Stream<R> map(Function<? super T, ? extends R> mapper);		
			
				1>说明:将流中的元素进行处理后,用新生成的元素代替原来的元素。注:新元素的类型与旧元素的类型可能不一样。
				2>参数:一个函数式接口,用传入的函数来生成新的元素。
				3>举例:Stream<String> stream = strList.stream().map(String::toUpperCase);
			
			<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
			
				说明:将流中的每个值都换成另一个流,然后把所有流连接成一个流。
			
			
			<R, A> R collect(Collector<? super T, A, R> collector);	
			
				1>说明:将流转换为其它形式,将流中的元素进行分组、拼接等。
				2>举例:
					List<String> list = strList.stream().map(String::toUpperCase).collect(Collectors.toList());

					Map<Long, Obj> map = objList.stream().collect(Collectors.toMap(Obj::getId, Function.identity(), (oldValue, newValue) -> oldValue));

					Map<String, List<BillDetail>> collect = detailList.stream().collect(Collectors.groupingBy(detail -> {
						return detail.getCode1() + detail.getCode2();
					}));
		

		3)Stream的终端操作
		
			void forEach(Consumer<? super T> action);	遍历流中的所有元素
			
			boolean allMatch(Predicate<? super T> predicate);	检查所有的元素是否都匹配
					anyMatch									检查是否有元素匹配
					noneMatch									检查是否有元素不匹配
			
			Optional<T> findFirst();							返回第一个元素
			Optional<T> findAny();								返回流中任意一个元素
			
			long count();										返回流中元素的总数
			Optional<T> max(Comparator<? super T> comparator);	返回流中最大的元素
			Optional<T> min(Comparator<? super T> comparator);	返回流中最小的元素
		
		
		说明:
			1>只有调用终端操作后,所有的中间操作才会去执行,若没有调用终端操作,那么所有的中间操作都将不会执行,这种模式叫做"惰性求值"。
			2>流只能使用一次,即只能调用一次终端操作。
	
	
	
	
	

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值