java8新特性

来源:互联网 发布:linux tee 命令 编辑:程序博客网 时间:2024/05/14 23:17

了解了一下java8的新特性,以下只列出了比较常用的一些新特性,还有许多用到的时候去查吧

以下用实例代码加注释的方式展示和说明这些新特性:

/** * @FunctionalInterface注解:确保接口只包含一个抽象方法,若标注了该注解且抽象方法不止一个,则会报错,若不加该注解,则可以有多个抽象方法 */@FunctionalInterfaceinterface Converter<F, T> {    T convert(F from);}/** * 此处看起来from是不是没有定义,却不报错?这是为什么呢? * 原来是因为上面的接口只有一个抽象方法。所以lambda表达式会自动的去匹配参数类型,从而自动编译该参数,像下面的main方法,Converter<String, Integer>此时已经知道F对应的是String类型,T对应的是Integer类型,而且上面的接口中唯一的抽象方法中的参数是F类型,所以自动的将下面的form认为是F类型,且会自动的正确编译该参数 * java8新特性的lambda表达式是个好东西,我也还在摸索当中,有什么不对的地方希望大家能指出来,一起学习,一起进步 * @param args */public static void main(String[] args) {Converter<String, Integer> converter = (from) -> Integer.valueOf(from);Integer converted = converter.convert("123");System.out.println(converted);//上面的代码还可以通过静态方法来引用,输出结果是一样的//Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用Converter<String, Integer> converter2 = Integer::valueOf;Integer converted2 = converter.convert("123");System.out.println(converted2);//startWith判断一个字符串是否以某某开头,若是,返回true,否则,返回falseString aString="ssssssssddd";Boolean aBoolean=aString.startsWith("a");System.out.println(aBoolean);//Lambda表达式中是无法访问到接口的默认方法的,java8允许接口中含有一个默认方法,实现该接口的类可以直接调用该默认方法//Predicate 接口只有一个参数,返回boolean类型。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非):Predicate<String> predicate = (s) -> s.length() > 0;predicate.test("foo");              // truepredicate.negate().test("foo");     // falsePredicate<Boolean> nonNull = Objects::nonNull;Predicate<Boolean> isNull = Objects::isNull;Predicate<String> isEmpty = String::isEmpty;Predicate<String> isNotEmpty = isEmpty.negate();//Function 接口有一个参数并且返回一个结果,并附带了一些可以和其他函数组合的默认方法(compose, andThen):Function<String, Integer> toInteger = Integer::valueOf;Function<String, String> backToString = toInteger.andThen(String::valueOf);String a=backToString.apply("123"); System.out.println(a);//Supplier 接口返回一个任意范型的值,和Function接口不同的是该接口没有任何参数Supplier<String> personSupplier = String::new;personSupplier.get();   // new String//Comparator 是老Java中的经典接口, Java 8在此之上添加了多种默认方法:Comparator<String> comparator = (p1, p2) -> p1.compareTo(p2);String p1 = new String("John");String p2 = new String("Alice");comparator.compare(p1, p2);             // > 0comparator.reversed().compare(p1, p2);  // < 0//java.util.Stream 表示能应用在一组元素上一次执行的操作序列。Stream 操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,这样你就可以将多个操作依次串起来。Stream 的创建需要指定一个数据源,比如 java.util.Collection的子类,List或者Set, Map不支持。Stream的操作可以串行执行或者并行执行。//首先看看Stream是怎么用,首先创建实例代码的用到的数据List:List<String> stringCollection = new ArrayList<>();stringCollection.add("ddd2");stringCollection.add("aaa2");stringCollection.add("bbb1");stringCollection.add("aaa1");stringCollection.add("bbb3");stringCollection.add("ccc");stringCollection.add("bbb2");stringCollection.add("ddd1");//Filter 过滤//过滤通过一个predicate接口来过滤并只保留符合条件的元素,该操作属于中间操作,所以我们可以在过滤后的结果来应用其他Stream操作(比如forEach)。forEach需要一个函数来对过滤后的元素依次执行。forEach是一个最终操作,所以我们不能在forEach之后来执行其他Stream操作。stringCollection    .stream()    .filter((s) -> s.startsWith("a"))    .forEach(System.out::println);//Sort 排序//排序是一个中间操作,返回的是排序好后的Stream。如果你不指定一个自定义的Comparator则会使用默认排序。stringCollection    .stream()    .sorted()    .filter((s) -> s.startsWith("a"))    .forEach(System.out::println);//需要注意的是,排序只创建了一个排列好后的Stream,而不会影响原有的数据源,排序之后原数据stringCollection是不会被修改的:System.out.println(stringCollection);// ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1//Map 映射//中间操作map会将元素根据指定的Function接口来依次将元素转成另外的对象,下面的示例展示了将字符串转换为大写字符串。你也可以通过map来讲对象转换成其他类型,map返回的Stream类型是根据你map传递进去的函数的返回值决定的。stringCollection    .stream()    .map(String::toUpperCase)    .sorted((b1, b2) -> b2.compareTo(b1))    .forEach(System.out::println);// "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"//Stream提供了多种匹配操作,允许检测指定的Predicate是否匹配整个Stream。所有的匹配操作都是最终操作,并返回一个boolean类型的值。boolean anyStartsWithA =     stringCollection        .stream()        .anyMatch((s) -> s.startsWith("a"));System.out.println(anyStartsWithA);      // trueboolean allStartsWithA =     stringCollection        .stream()        .allMatch((s) -> s.startsWith("a"));System.out.println(allStartsWithA);      // falseboolean noneStartsWithZ =     stringCollection        .stream()        .noneMatch((s) -> s.startsWith("z"));System.out.println(noneStartsWithZ);      // true//Count 计数//计数是一个最终操作,返回Stream中元素的个数,返回值类型是long。long startsWithB =     stringCollection        .stream()        .filter((s) -> s.startsWith("b"))        .count();System.out.println(startsWithB);    // 3//Reduce 规约//这是一个最终操作,允许通过指定的函数来讲stream中的多个元素规约为一个元素,规越后的结果是通过Optional接口表示的:Optional<String> reduced =    stringCollection        .stream()        .sorted()        .reduce((s1, s2) -> s1 + "#" + s2);reduced.ifPresent(System.out::println);// "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"//并行Streams//串行Stream上的操作是在一个线程中依次完成,而并行Stream则是在多个线程上同时执行。//并行版的快了50%之多,唯一需要做的改动就是将stream()改为parallelStream()。//Map//Map类型不支持stream,不过Map提供了一些新的有用的方法来处理一些日常任务。Map<Integer, String> map = new HashMap<>();for (int i = 0; i < 10; i++) {    map.putIfAbsent(i, "val" + i);}//map.forEach((id, val) -> System.out.println(val));//以上代码很容易理解, putIfAbsent 不需要我们做额外的存在性检查,而forEach则接收一个Consumer接口来对map里的每一个键值对进行操作。//以下是map的其它新特性map.computeIfPresent(3, (num, val) -> val + num);map.get(3);             // val33map.computeIfPresent(9, (num, val) -> null);map.containsKey(9);     // falsemap.computeIfAbsent(23, num -> "val" + num);map.containsKey(23);    // truemap.computeIfAbsent(3, num -> "bam");map.get(3);             // val33//如何在Map里删除一个键值全都匹配的项:map.remove(3, "val3");map.get(3);             // val33map.remove(3, "val33");map.get(3);             // null//有这个键则取此键的值,否则取默认值,此处为"not found"map.getOrDefault(42, "not found");  // not found//Map的元素做合并也变得很容易了://Merge做的事情是如果键名不存在则插入,否则则对原键对应的值做合并操作并重新插入到map中。map.merge(9, "val9", (value, newValue) -> value.concat(newValue));map.get(9);             // val9map.merge(9, "concat", (value, newValue) -> value.concat(newValue));map.get(9);             // val9concat}

到这儿差不多了,其他的基本上用的比较少,比如说注解,这些东西需要用到的时候再去找度娘吧,学习当中,有什么不对的地方各位提出来,一起学习,一起进步

原创粉丝点击