1、Lambda表达式
语法由参数列表、箭头符号 -> 和函数体组成。函数体既可以是一个表达式,也可以是一个代码块。
(parameters) -> expression 或者 (parameters) -> { statements; }
表达式后面是没有分号的,如果只有一个参数,那么包围参数的圆括号可以省略。
任何可以接受一个FI实例的地方,都可以用Lambda表达式。
lambda语法
1、一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数
2、一个箭头符号:->
3、方法体,可以是表达式和代码块。
2、函数式接口
函数式接口(Functional Interface)是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
Java8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查。
函数式接口可以被隐式转换为 lambda 表达式。
函数式接口里允许定义默认方法。
函数式接口里允许定义静态方法。
Object 类的public同名方法不算抽象方法。
内置函数式接口:
Function 一元函数: Function<T, R> R apply(T t);
BiFunction 二元函数: BiFunction<T, U, R> R apply(T t, U u);
UnaryOperator 一元算子:输入输出同类型 UnaryOperator<T> T apply(T t);
BinaryOperator 二元算子:输入输出同类型 BinaryOperator<T> T apply(T t, T t);
Predicate 一元断言:返回boolean Predicate<T> boolean test(T t);
BiPredicate 二元断言:返回boolean BiPredicate<T, U> boolean test(T t, U u);
Consumer 一元消费者:无返回值 Consumer<T> void accept(T t);
BiConsumer 二元消费者:无返回值 BiConsumer<T, U> void accept(T t, U u);
Supplier 供应者:无参,只有返回值 Supplier<T> T get();
如定义了一个函数式接口如下:
@FunctionalInterface interface GreetingService{ //抽象方法 void sayMessage(String message); //默认方法:只需在方法名前面加个default关键字即可。 default void doWork1(){ //Method body } //静态方法 static void printHello(){ System.out.println("Hello"); } }
那么就可以使用Lambda表达式来表示该接口的一个实现(JAVA8之前一般是用匿名类实现的):
GreetingService greetService1 = message -> System.out.println("Hello " + message);
3、方法引用
语法:
左边是容器(可以是类名,实例名),中间是"::",右边是相应的方法名
一般方法的引用格式
如果是静态方法,则是ClassName::methodName
如果是实例方法,则是Instance::methodName
如果是构造函数,则是ClassName::new
超类上的实例方法:super::methodName
数组构造方法:TypeName[]::new
4、Stream 串行流
Stream(流)是一个来自数据源的元素队列并支持聚合操作
/** * Stream: * findFirst:取集合第一个元素 * min:取集合的最小值 * max:取集合的最大值 * forEach:集合循环处理 * forEachOrdered:严格顺序循环处理 * filter:过滤 * sorted:排序,n1-n2大于升序,n2-n1大于降序 * map:值转换处理 * mapToXXX:值转成XXX型 * flatMap:将一个2维的集合转成1维度 * collect:集合归并处理 * allMatch:所有元素都满足条件才返回true * anyMatch:任一元素满足条件则返回true * noneMatch:无一元素满足条件才返回true * reduce:a[0]与a[1]进行二合运算,结果与a[2]做二合运算,以此类推。求和、求最大、最小值等 * reducing: * distinct:去掉重复值 * peek:对每个元素执行操作并返回一个新的 Stream * limit:限制最大数量 * skip:忽略指定个数 * parallel:转成并行流 */ private static void testStream(){ Integer value; List<Integer> numbers = Arrays.asList(29, 19, 5, 11, 7, 13, 11, 3, 13, 2); List<String> list3 = Arrays.asList("k1|v1", "k2|v3", "k3|v3", "k4|v4", "k5|v5"); //取第一个元素 value = numbers.stream().findFirst().get(); //取集合的最小值、最大值 value = numbers.stream().min((m, n) -> m-n).get(); value = numbers.stream().min(Integer::min).get(); value = numbers.stream().max((m, n) -> m-n).get(); value = numbers.stream().max(Integer::max).get(); //forEach numbers.stream().forEach(n -> System.out.print(String.valueOf(n) + ", ")); //生成0-100的随机数,取10个,升序排序 new Random().ints(0, 100).limit(10).sorted().forEach(System.out::println); //forEachOrdered numbers.stream().forEachOrdered(n -> System.out.print(String.valueOf(n) + ", ")); //filter 过滤出大于5的数值,sorted 升序排序,map 各元素值减1,collect 数值归并成一个List集合 List<Integer> list = numbers.stream().filter(n -> n>5) .sorted((n1, n2) -> n1-n2).map(n -> n-1).collect(Collectors.toList()); //多个过滤条件 Predicate<Integer> p1 = (n) -> n>12; Predicate<Integer> p2 = (n) -> n<20; List<Integer> list2 = numbers.stream().filter(p1.and(p2)).collect(Collectors.toList()); //mapToInt:转成IntStream //summaryStatistics:取得个数、最小值、最大值、总和以及平均值 IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("count: " + stats.getCount()); System.out.println("min: " + stats.getMin()); System.out.println("max: " + stats.getMax()); System.out.println("sum: " + stats.getSum()); System.out.println("average: " + stats.getAverage()); //求和: rangeClosed 生成某个范围的数值 value = IntStream.rangeClosed(1, 10).boxed().mapToInt(Integer::intValue).sum(); //flatMap:将一个2维的集合转成1维度 list3.stream().flatMap(item -> Arrays.stream(item.split("\\|"))).collect(Collectors.toList()).forEach(System.out::print); //xxxMatch 元素条件判断 boolean b = numbers.stream().allMatch(n -> n>19); //所有元素都满足条件才返回true b = numbers.stream().anyMatch(n -> n>0); //任一元素满足条件则返回true b = numbers.stream().noneMatch(n -> n>30); //无一元素满足条件才返回true //reduce做求和处理 value = numbers.stream().reduce((sum, x) -> sum + x).get(); value = numbers.stream().reduce(0, Integer::sum); //sum的初始值为0 //reducing: sum的初始值为0,每个元素值+1,最后求和 value = Arrays.asList(1, 3, 5).stream().collect(Collectors.reducing(0, x -> x+1, (sum, n) -> sum+n)); //distinct 去掉重复值 List<Integer> list1 = numbers.stream().distinct().collect(Collectors.toList()); //map:数值转换处理,对列表的每个元素应用函数 String.valueOf(x-1) //distinct:去重,joining:用分号连接各元素为一个字符串 String value2 = numbers.stream().map((x) -> String.valueOf(x-1)) .distinct().collect(Collectors.joining(";")); //peek:对每个元素执行操作并返回一个新的 Stream //limit:限制返回的个数 //skip:忽略指定个数 List<String> list5 = Stream.of("11", "one", "two", "three", "four") .filter(e -> e.length() > 2) .peek(e -> System.out.println("Filtered value: " + e)) .map(String::toUpperCase) .peek(e -> System.out.println("Mapped value: " + e)) .limit(3) .skip(2) .collect(Collectors.toList()); }
//排序: Comparator类的用法
//普通排序 List<Integer> numbers = Arrays.asList(29, 5, 13, 3, 18, 2); //numbers.stream().sorted().forEach(s -> System.out.print(s + " ")); //numbers.stream().sorted(Comparator.naturalOrder()).forEach(s -> System.out.print(s + " ")); //自然顺序 numbers.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.print(s + " ")); //降序 List<Person> list = new ArrayList<>(); list.add(new Person("name6", 29)); list.add(new Person("name5", 19)); list.add(new Person("name1", 29)); list.add(new Person("name3", 22)); list.add(new Person("name4", 19)); list.add(new Person("name2", 22)); //先按age升序,然后反转变为降序 list.stream() .sorted(Comparator.comparing(Person::getAge).reversed()) .forEach(System.out::println); //按age降序 list.stream() .sorted(Comparator.comparing(Person::getAge, Comparator.reverseOrder())) .forEach(System.out::println); //多字段排序:先按age降序,然后按name升序 list.stream() .sorted(Comparator.comparing(Person::getAge, Comparator.reverseOrder()).thenComparing(Person::getName)) .forEach(System.out::println);
5、parallelStream 并行流
paralleStream里直接修改变量是非线程安全的,但是采用collect和reduce操作可以满足线程安全。
parallelStream只是做到别浪费cpu,cpu负载大不要用。
不要在多线程中使用parallelStream。
请确保每条处理无状态且没有关联。
N可用的数据量 x Q对每个元素执行的计算量 > 10000 就会获得有效提升
list.parallelStream().sorted((n1, n2) -> n1-n2).collect(Collectors.toList()); //通过加锁保证parallel并行处理是线程安全的 Lock lock = new ReentrantLock(); IntStream.range(0, 10000).parallel().forEach(i -> { lock.lock(); try { list.add(i); }finally { lock.unlock(); } });
6、Collectors
/** * Collectors:收集器 * toList:汇集为List * toSet:汇集为Set * toMap:汇集为Map * toCollection:转换成特定的集合 * joining:连接成字符串 * averagingInt:求平均值 * minBy:求最小值 * maxBy:求最大值 * summingInt:求和 * summarizingXXX:可以获取最大值、最小值、平均值、总和值、总数 * mapping: 先对集合中的元素进行映射,然后再对映射的结果使用Collectors操作 * groupingBy:分组汇集,返回Map * groupingByConcurrent:分组汇集,返回ConcurrentMap * mapping: 先对集合中的元素进行映射,然后再对映射的结果使用Collectors操作 * partitioningBy:用于分成两组的情况,一组true,一组false * reducing:累计处理 */ private static void testCollectors(){ Integer value; List<Integer> numbers = Arrays.asList(29, 19, 5, 11, 7, 13, 11, 3, 13, 2); List<String> list3 = Arrays.asList("k1|v1", "k2|v2", "k3|v3", "k4|v4", "k5|v5"); //toList List<Integer> list = numbers.stream().filter(n -> n>10).collect(Collectors.toList()); //toSet Set<Integer> set = numbers.stream().filter(n -> n>10).collect(Collectors.toSet()); //toMap Map<String, String> map3 = numbers.stream().collect(Collectors.toSet()).stream().collect(Collectors.toMap(k -> "key"+k, v -> "value"+v)); map3.forEach((k,v) -> { System.out.println(k + "=" + v); }); //toCollection:转换成特定的集合 TreeSet<Integer> treeSet = numbers.stream().collect(Collectors.toCollection(TreeSet::new)); //joining:连接成一个字符串 String result = list3.stream().collect(Collectors.joining(", ")); //averagingInt 计算平均值 Double average = numbers.stream().collect(Collectors.averagingInt(n -> n)); //最小值 minBy value = numbers.stream().collect(Collectors.minBy((x, y) -> x - y)).get(); //最大值 maxBy value = numbers.stream().collect(Collectors.maxBy((x, y) -> x - y)).get(); //求和 summingInt value = numbers.stream().collect(Collectors.summingInt(n -> n)); //summarizingInt IntSummaryStatistics stat = numbers.stream().collect(Collectors.summarizingInt(n -> n)); System.out.println(stat.getCount()); System.out.println(stat.getMin()); System.out.println(stat.getMax()); System.out.println(stat.getSum()); System.out.println(stat.getAverage()); //mapping: 先对集合中的元素进行映射,然后再对映射的结果使用Collectors操作 String value3 = numbers.stream().collect(Collectors.mapping(n -> String.valueOf(n+10), Collectors.joining(","))); //分组 Map<Integer, List<Integer>> map1 = numbers.stream().collect(Collectors.groupingBy(n -> n)); //数据分组 //分组汇集,返回ConcurrentMap ConcurrentMap<Integer, List<Integer>> map2 = numbers.stream().collect(Collectors.groupingByConcurrent(n -> n)); //数据分组,对每组的值计算count Map<Integer, Long> map = numbers.stream().collect(Collectors.groupingBy(n -> n, Collectors.counting())); //partitioningBy 用于分成两组的情况,一组true,一组false Map<Boolean, List<Integer>> map4 = numbers.stream().collect(Collectors.partitioningBy(n -> n%2==0)); //reducing: sum的初始值为0,每个元素值+1,最后求和 value = Arrays.asList(1, 3, 5).stream().collect(Collectors.reducing(0, x -> x+1, (sum, n) -> sum+n)); }
7、Optional
Optional是Java8提供的为了解决null安全问题的一个API。Optional仅仅是一个容器:存放T类型的值或者null。
//value is null Address addr = null; String city = Optional.ofNullable(addr).map(a -> a.getCity()).orElseGet(() -> "none"); System.out.println(city); //值存在则isPresent()方法会返回true System.out.println(Optional.empty().isPresent()); System.out.println(Optional.of(100).isPresent()); //value is not null addr = new Address("province", "city"); city = Optional.ofNullable(addr).map(a -> a.getCity()).orElse("Unknown"); System.out.println(city); //value is null,throw exception User user = null; try{ city = Optional.ofNullable(user) .map(u -> u.getAddress()) .map(a -> a.getCity()) .orElseThrow(() -> new IllegalArgumentException("The value of param user isn't available")); }catch(Exception ex){ ex.printStackTrace(); } //filter user = new User(1L, "uid", "pwd", addr); Optional<User> optional = Optional.ofNullable(user) .filter(u -> u.getId() == 1); if(optional.isPresent()){ System.out.println(optional.get().getUsername()); }
8、用ScriptEngine动态执行JS
ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine engine = scriptEngineManager.getEngineByName("nashorn"); //js value Integer result = (Integer) engine.eval("10 + 2"); System.out.println(result); engine.eval("var username='cjm'; password='123'; var array=['A','B','C']; var json={uid:'cjm', age:40};"); System.out.println(engine.get("username")); ScriptObjectMirror array = (ScriptObjectMirror)engine.get("array"); System.out.println(array.getSlot(1)); ScriptObjectMirror json = (ScriptObjectMirror) engine.get("json"); System.out.println(json.get("uid")); engine.put("age", 35); engine.eval("var age = age - 5"); System.out.println(engine.get("age")); //js Object engine.eval("var obj=new Object(); obj.info='object info'; obj.getInfo=function(){return this.info;}; "); ScriptObjectMirror obj = (ScriptObjectMirror) engine.get("obj"); System.out.println(obj.get("info")); System.out.println(obj.get("getInfo")); System.out.println(engine.eval("obj.getInfo()")); //将变量导入js脚本 Map<String, Object> input = new TreeMap<>(); input.put("a", 3); input.put("b", 4); System.out.println(engine.eval("Math.pow(a,b)", new SimpleBindings(input))); //调用js函数 engine.eval("function add (a, b) {return a+b;}"); Invocable jsInvoke = (Invocable) engine; Object value = jsInvoke.invokeFunction("add", new Object[] {10, 5}); System.out.println(value);
9、Base64
//Encoder String value = Base64.getEncoder().encodeToString("username:用户名".getBytes("utf-8")); System.out.println(value); byte[] bytes = Base64.getDecoder().decode(value); System.out.println(new String(bytes, "utf-8")); //UrlEncoder value = Base64.getUrlEncoder().encodeToString("http://www.baidu.com?uid=张三&pwd=123".getBytes("utf-8")); System.out.println(value); bytes = Base64.getUrlDecoder().decode(value); System.out.println(new String(bytes, "utf-8")); //MimeEncoder StringBuilder sb = new StringBuilder(); for (int i=0; i<10; i++) { sb.append(UUID.randomUUID().toString()); } byte[] mimeBytes = sb.toString().getBytes("utf-8"); value = Base64.getMimeEncoder().encodeToString(mimeBytes); System.out.println(value); bytes = Base64.getMimeDecoder().decode(value); System.out.println(new String(bytes, "utf-8"));
10、并行数组
long[] arr = new long [10]; //生成随机数,放到一个数组里 Arrays.parallelSetAll(arr, x -> ThreadLocalRandom.current().nextInt(100)); Arrays.stream(arr).limit(10).forEach(i -> System.out.print(i + " ")); System.out.println(); //数组并行排序 Arrays.parallelSort(arr); System.out.println();
11、日期时间处理
jdk8新增一个新的日期时间处理包java.time,该包中的类是不可变且线程安全的。主要的类包括:LocalDate、LocalTime、LocalDateTime、ZonedDateTime、时钟Clock、时间戳Instant、时段Period等。
相关推荐
本视频为java8新特性,百度云链接和密码,永久有效,失效联系我
Java8是Java编程语言的一次重大更新,引入了许多新的特性和功能,极大地提升了开发效率和代码的可读性。以下是一些主要的Java8新特性详解: 1. **Lambda表达式**:Lambda表达式是Java8中最显著的新特性,它为Java...
Java 8是Java语言发展的一个重要里程碑,引入了许多创新性的特性和改进,...黑马程序员的Java8新特性详解笔记和源码提供了深入学习这些概念的资源,结合实际的代码示例,将有助于你更好地理解和掌握Java 8的核心特性。
在Java 8中,最重要的两个新特性无疑是Lambda表达式和Stream API。这两个特性都与函数式编程思想密切相关,让Java开发者能够更加灵活地处理数据。 ### Lambda表达式 Lambda表达式是Java 8中最显著的新特性之一,它...
根据提供的文件信息,我们可以深入探讨Java 8的新特性。这些特性极大地提高了Java语言的功能性和效率,使得开发人员能够编写更加简洁、高效的代码。 ### Java 8 新特性概述 #### Lambda 表达式 Lambda表达式是Java...
尚硅谷Java视频Java8新特性视频教程尚硅谷Java视频Java8新特性视频教程尚硅谷Java视频Java8新特性视频教程
Java 8是Java语言发展的一个重要里程碑,引入了许多创新特性,极大地提升了开发效率和代码质量。以下是关于Java 8新特性的详细讲解: ...通过观看“Java8 新特性视频教程”,你可以深入理解并熟练运用这些特性。
这个压缩包文件“基于java8新特性+反射机制实现list不同实体类互转.zip”提供了一种解决方案,它利用了Java 8的新特性和反射机制来实现这种转换,并将这个功能封装为一个工具类。 首先,Java 8引入了许多新特性,...
Java 8 新特性 ---- 代码 Java 8 新特性 ---- 代码 Java 8 新特性 ---- 代码 Java 8 新特性 ---- 代码 Java 8 新特性 ---- 代码 Java 8 新特性 ---- 代码 Java 8 新特性 ---- 代码 Java 8 新特性 ---- 代码 Java 8 ...
java8新特性-1-函数式编程.pptxjava8新特性-1-函数式编程.pptx
但是我们实际开发中真正用到的新特性并不多,大多数人也仅仅用用lambda,而对于其他的特性,比如:多重注解、Date API、函数式接口等等并没有使用起来,本资源包含作者的学习java8新特性的笔记,笔记中有讲解和代码...