Java 8 新特性

Java 8 新特性


lambda表达式

Lambda表达式(也称为闭包),Lambda允许把函数作为一个方法的参数.

Lambda 表达式由三个部分组成:
第一部分:一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数
第二部分:一个箭头符号:->
第三部分:方法体,可以是表达式和代码块

Lambda Expressions syntax is (argument) -> (body)

函数式接口

如果一个接口定义个唯一一个抽象方法,那么这个接口就称为函数式接口.通常使用@FunctionalInterface注解

默认方法与静态方法并不影响函数式接口的契约,可以任意使用.

Runnable接口是一个典型的函数式接口.
    Runnable runnable = () ->
    {
        System.out.println("new way create Runnable instance");
    };


@FunctionalInterface
public interface FunctionalDefaultMethods {
    void method();
    default void defaultMethod() {            
    }        
}

例子演示

函数式接口结合lambda表达式

@FunctionalInterface
public interface FunctionInterface
{
    int operate(int a, int b);
}


public class MainApp
{
    public static void main(String[] args)
    {
        FunctionInterface addFunction = (a, b) -> a + b;
        FunctionInterface subFunction = (a, b) -> a - b;
        FunctionInterface mulFunction = (a, b) -> a * b;
        FunctionInterface divFunction = (a, b) -> a / b;

        System.out.println(addFunction.operation(10, 5));
        System.out.println(subFunction.operation(10, 5));
        System.out.println(mulFunction.operation(10, 5));
        System.out.println(divFunction.operation(10, 5));
    }
}

使用forEach方法

@Test
public void testForEach()
{
    List<String> languages = Arrays.asList("java", "C", "C++", "C#", "JavaScript");
    languages.forEach(e ->
    {
        System.out.print(e + " , ");
    });

    List<String> list = new ArrayList<>();
    languages.forEach(e ->
    {
        list.add(e);
    });
    System.out.println(list);
}

使用lambda表达式应用Runnable接口

    Runnable runnable = () ->
    {
        System.out.println(Thread.currentThread().getName());
        System.out.println("hello world");
    };

    new Thread(runnable).start();

Stream API

A new java.util.stream perform filter/map/reduce like operations with the collection.


Stream流操作是Java 8对集合操作的性能提升手段,记住Stream操作是不会改变原来集合的数据的.

stream和parallelStream方法

@Test
public void testStreamAPI()
{
    List<Integer> myList = new ArrayList<>();
    for (int i = 0; i < 5; i++)
        myList.add(i);

    // 串行计算
    List<Integer> sequentialList = myList.stream().filter(num -> num > 2).collect(Collectors.toList());
    // 并行计算(在大集合和多CPU场景下可以发挥更高性能)
    List<Integer> parallelList = myList.parallelStream().filter(num -> num > 2).collect(Collectors.toList());

    System.out.println(myList);
    System.out.println(sequentialList);
    System.out.println(parallelList);

}

备注:
Notice that parallel processing values are not in order,
so parallel processing will be very helpful while working with huge collections.

测试Stream filter方法

@Test
public void testFilter()
{
    List<String> languages = Arrays.asList("java", "C", "C++", "C#", "JavaScript", null);

    languages.stream().filter(e -> e != null && e.length() > 3).forEach(e ->
    {
        System.out.println(e);
    });

    List<String> list = languages.stream().filter(e -> e != null && e.length() > 2).collect(Collectors.toList());
    System.out.println(list);

}

测试Stream map方法(映射)
@Test
public void testStreamMap()
{
    List<String> languages = Arrays.asList("java", "C", "C++", "C#", "JavaScript", null);

    List<String> list = languages.stream().filter(e -> e != null)
    .map(e -> e.toUpperCase() + "-language").collect(Collectors.toList());

    System.out.println(list);
}

测试Stream reduce方法(归约)   

@Test
public void testReduce()
{
    List<String> languages = Arrays.asList("java", "C", "C++", "C#", "JavaScript", null);

    String count = languages.stream().filter(e -> e != null)
    .map(e -> e.toUpperCase()).reduce((a, b) -> a = a + b).get();

    System.out.println(count);
}

测试Stream sorted方法(排序)

@Test
public void testStreamSort()
{
    List<String> languages = Arrays.asList("java", "C", "C++", "C#", "JavaScript");
    //顺序排
    List<String> orderSortLanguage = languages.stream().sorted().collect(Collectors.toList());
    //倒序排
    List<String> reverseSortLanguage = languages.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

    System.out.println(languages);
    System.out.println(orderSortLanguage);
    System.out.println(reverseSortLanguage);
}

测试Stream count方法(求集合元素个数)

Stream<Integer> numbers1 = Stream.of(1,2,3,4,5);

System.out.println("Number of elements in stream="+numbers1.count()); //5

测试Stream forEach方法

@Test
public void testForEach()
{
    List<String> languages = Arrays.asList("java", "C", "C++", "C#", "JavaScript");
    languages.forEach(e ->
    {
        System.out.print(e + " , ");
    });

}

测试Stream match方法

@Test
public void testMatch()
{
    List<String> languages = Arrays.asList("java", "C", "C++", "C#", "JavaScript");

    boolean jLanguage = languages.stream().allMatch(e -> e.startsWith("j"));
    System.out.println(jLanguage);
}

测试Stream findFirst方法
@Test
public void testFindFirst()
{
    Stream<String> names4 = Stream.of("Pankaj", "Amit", "David", "Lisa");

    Optional<String> firstNameWithD = names4.filter(i -> i.startsWith("D")).findFirst();
    if (firstNameWithD.isPresent())
    {
        System.out.println("First Name starting with D=" + firstNameWithD.get()); // David
    }
}

创建流
1、使用Stream的静态方法of(T ...value)创建流

    Stream<Integer> stream = Stream.of(1, 2, 3, 4);
    Stream<Integer> stream = Stream.of(new Integer[]{1,2,3,4});

2、使用Collection的stream()或parallelStream()创建流

    Collection<String> collection = new ArrayList<>();
    Stream<String> sequentialStream=collection.stream();
    Stream<String> parallelStream=collection.parallelStream();

3、使用Stream.generate()和Stream.iterate()创建流 

    Stream<String> stream1 = Stream.generate(() -> {return "abc";});
    Stream<String> stream2 = Stream.iterate("abc", (i) -> i);

4、使用Arrays.stream()和String.chars()创建流

    LongStream longStream = Arrays.stream(new long[]{1,2,3,4});
    IntStream intStream = "abc".chars();

将Stream转换为集合或数组

1、 使用collect()方法从Stream中获得List,Map,Set.

Stream<Integer> intStream = Stream.of(1,2,3,4);
List<Integer> intList = intStream.collect(Collectors.toList());
System.out.println(intList); //prints [1, 2, 3, 4]

intStream = Stream.of(1,2,3,4); //stream is closed, so we need to create it again
Map<Integer,Integer> intMap = intStream.collect(Collectors.toMap(i -> i, i -> i+10));
System.out.println(intMap); //prints {1=11, 2=12, 3=13, 4=14}


2、使用toArray()方法从Stream中获得数组
Stream<Integer> intStream = Stream.of(1,2,3,4);
Integer[] intArray = intStream.toArray(Integer[]::new);
System.out.println(Arrays.toString(intArray)); //prints [1, 2, 3, 4]

相关概念

Java 8 Stream API 常用的函数式接口

Function and BiFunction

 Function represents a function that takes one type of argument and returns another type of argument.

    Function<T, R>

    BiFunction<T, U, R>

Stream 方法

    <R> Stream<R> map(Function<? super T, ? extends R> mapper)
    IntStream mapToInt(ToIntFunction<? super T> mapper)
    IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper)
    <A> A[] toArray(IntFunction<A[]> generator)
    <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)

Predicate and BiPredicate

It represents a predicate against which elements of the stream are tested. 
This is used to filter elements from the java stream.

Just like Function, there are primitive specific interfaces for int, long and double.

    Predicate<T>

    BiPredicate<T, U>

Stream 方法:
        Stream<T> filter(Predicate<? super T> predicate)
        boolean anyMatch(Predicate<? super T> predicate)
        boolean allMatch(Predicate<? super T> predicate)
        boolean noneMatch(Predicate<? super T> predicate)

Consumer and BiConsumer

 It represents an operation that accepts a single input argument and returns no result. 
 It can be used to perform some action on all the elements of the java stream.

    Consumer<T> 
    BiConsumer<T, U>

Stream 方法:

    Stream<T> peek(Consumer<? super T> action)
    void forEach(Consumer<? super T> action)
    void forEachOrdered(Consumer<? super T> action)

Supplier

Supplier represent an operation through which we can generate new values in the stream. 

    Supplier<T>

Stream 方法

    public static<T> Stream<T> generate(Supplier<T> s)
    <R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner)

java.util.Optional

Java Optional is a container object which may or may not contain a non-null value. 
If a value is present, isPresent() will return true and get() will return the value. 

Stream 方法

    Optional<T> reduce(BinaryOperator<T> accumulator)
    Optional<T> min(Comparator<? super T> comparator)
    Optional<T> max(Comparator<? super T> comparator)
    Optional<T> findFirst()
    Optional<T> findAny()

Java 8 日期类型

针对java日期类型的处理不便,java 8提供了新的日期支持.

参考

1、http://www.journaldev.com/2389/java-8-features-with-examples
2、http://www.journaldev.com/2752/java-8-interface-changes-static-method-default-method
3、http://www.journaldev.com/2763/java-8-functional-interfaces
4、http://www.journaldev.com/2774/java-8-stream
5、http://www.journaldev.com/2800/java-8-date-localdate-localdatetime-instant

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值