学了忘忘了看之Java8

Java8语法基本使用

lambda表达式使用

lambda表达式基本概念

只需要知道lambda表达式主要功能是用来实现接口的和匿名内部类差不多,而且实现的是一个只有一个抽象方法的接口(函数式接口,被@FunctionalInterface注释)

快速入门案例

public class APP1 {

    public static void main(String[] args) {

        //使用匿名内部类实现Runnable接口
        new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("hello java8");
            }

        }).start();

        //使用lambda表达式实现Runnable接口
        new Thread(() -> System.out.println("Hello java8 Lambda!!!") ).start();

    }

}

基本语法

() -> {}                            相当于        一个public void xxx(){ }方法

() -> "hello world"                 相当于        一个public String xxx(){ return "hello world"; }方法,返回类型会自动根据返回值设置

() -> { return "hello world"; }     相当于        () -> "hello world"的显式写法

() -> { return "hello world" ; }     相当于        () -> "hello world"的显式写法

int -> { return "hello world" + int ; }     相当于      一个public String xxx(int i){ return "hello world" + i; }

(int,int) -> { return "hello world" + int ; }     相当于      一个public String xxx(int i){ return "hello world" + i; }

注意:
1. ()中的是参数变量名称,可以随意定义
2. (int a,String b) -> a + b,当有两个参数的时候可以给起指定上类型

java8新增的函数式接口

java8新增函的数式接口位于java.util.function包下,以下为常用的几个函数式接口:

Interface Predicate<T>
    default Predicate<T> and(Predicate<? super T> other)
        Returns a composed predicate that represents a short-circuiting logical AND of this predicate and another.
    static <T> Predicate<T> isEqual(Object targetRef)
        Returns a predicate that tests if two arguments are equal according to Objects.equals(Object, Object).
    default Predicate<T> negate()
        Returns a predicate that represents the logical negation of this predicate.
    default Predicate<T> or(Predicate<? super T> other)
        Returns a composed predicate that represents a short-circuiting logical OR of this predicate and another.
    boolean test(T t)  //返回boolean形值
        Evaluates this predicate on the given argument. 

Interface Consumer<T>
    void accept(T t) //无返回值
        Performs this operation on the given argument.
    default Consumer<T> andThen(Consumer<? super T> after)
        Returns a composed Consumer that performs, in sequence, this operation followed by the after operation. 

Interface Function<T,R>
    default <V> Function<T,V> andThen(Function<? super R,? extends V> after)
        Returns a composed function that first applies this function to its input, and then applies the after function to the result.
    R apply(T t)  //返回R这个类型的值
        Applies this function to the given argument.
    default <V> Function<V,R> compose(Function<? super V,? extends T> before)
        Returns a composed function that first applies the before function to its input, and then applies this function to the result.
    static <T> Function<T,T> identity()
        Returns a function that always returns its input argument.

函数式接口的使用例子

下面的例子只是为了举例子而举例子,具体怎么用还是根据情况需要而定,当java api提供的函数式接口不够用,那么就可以自定义;

自定义函数式接口使用例子:

public class APP2 {

    public static void main(String[] args) {
        /**
         * 这里的a和b实质值就是1和2
         * (a,b) -> a + b相当于一个Count接口的实现,count方法体就是 return a + b;
         * 所以,count.count(a, b)就return了一个3
         */
        count(1,2,(a,b) -> a + b);
    }

    //计算a+b
    public static void count(int a, int b, Count count) {

        System.out.println(count.count(a, b));

    }

}

//被该注解注释的接口只能有一个抽象方法
@FunctionalInterface
interface Count{
    int count(int a, int b);
}

Predicate

import java.util.function.Predicate;

public class APP3 {

    public static void main(String[] args) {

        checkAge( new Person("谭迪", 21), (Person) -> Person.age>=18 );
    }

    //判断person是否成年
    public static void checkAge(Person person, Predicate<Person> predicate) {
        if(predicate.test(person)) {
            System.out.println(person.name + "你已经成年,时光飞逝,请你珍惜接下来的日子。");
        } else {
            System.out.println(person.name + "你还是个宝宝!!!");
        }
    }

}

class Person {
    String name;
    int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Consumer

import java.util.function.Consumer;

public class APP4 {

    public static void main(String[] args) {
           //lambda表达式如果参数只有一个,()可以省去,但无参数时要加上
        sayHello("hello", String -> {
            for(int i=0; i<10; i++) {
                System.out.println(String + "-" +i);
            }
        } );
    }

    //打印10次 hello java
    public static void sayHello(String str,Consumer consumer) {
        consumer.accept(str);
    }

}

Function

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

public class APP5 {

    public static void main(String[] args) {
        List<Apple> list = new ArrayList<>();
        list.add(new Apple("绿色"));
        list.add(new Apple("红色"));
        list.add(new Apple("蓝色"));
        list.add(new Apple("红色"));
        list.add(new Apple("黑色"));

        List<Apple> redApples = returnRedApple(list, List -> {
            List<Apple> newList = new ArrayList<>();
            for (Apple apple : list) {
                if("红色".equals(apple.color)) {
                    newList.add(apple);
                }
            }
            return newList;
        });

        System.out.println("红苹果有" + redApples.size() + "个");

    }

    //选出红色的苹果
    public static List<Apple> returnRedApple(List<Apple> source, Function<List<Apple>,List<Apple>> function){
        return function.apply(source);
    }

}

class Apple{
    String color;
    public Apple(String color) {
        this.color = color;
    }
}

方法引用

当你了解了lambda表达式,那么再来了解方法引用其实是很容易的,方法引用也是对函数式接口的实现;

快速入门例子:


//Function<String,Integer> function = (String str) -> Integer.parseInt(str);  //lambda表达式

/**说明:
 * Function<String,Integer> function = Integer::parseInt;
 * Integer::parseInt对应的类型一定是Function<T,R>中的R类型,因为Function<T,R>中的抽象方法是 R apply(T t)
 */
Function<String,Integer> function = Integer::parseInt; //方法调用

Integer apply = function.apply("100");
System.out.println(apply); //100

图解:

例子2:

public class APP1 {

    public static void main(String[] args) {
        //利用方法引用调用构造方法
        Function<String,Apple> function = Apple::new;
        Apple apple = function.apply("紫色");
        System.out.println(apple.color);
    }

}

class Apple{
    String color;
    public Apple(String color) {
        this.color = color;
    }
}

接口新特性

静态方法

public class APP3{
    public static void main(String[] args) {

        Test test = System.out::println;
        test.sayHello("谭迪"); //实现方法
        test.defaultSayHello("小明"); //默认方法

    }
}

interface Test {

    //默认方法:需要实现了该接口才能调用该方法
    default void defaultSayHello(String name) {
        System.out.println(name + "你好!!!");
    }

    void sayHello(String name);
}

默认方法

public class APP3{
    public static void main(String[] args) {
        Test.sayHello("谭迪");
    }
}

interface Test {

    //静态方法:注意接口中的静态方法只能是public和默认修饰
    static void sayHello(String name) {
        System.out.println(name + "你好!!!");
    }
}

Stream API(流)

什么是流?

你可以将它理解成一个遍历数据集合的高级迭代器 -- 来自Java8实战

快速入门例子

public class APP4 {

    public static void main(String[] args) {

        List<Person> list = new ArrayList<>();
        list.add(new Person("张三", 20,"广东"));
        list.add(new Person("李四", 16,"四川"));
        list.add(new Person("王五", 29,"广东"));
        list.add(new Person("赵六", 11,"广西"));
        list.add(new Person("孙7", 30,"广东"));

        /**
         * 使用Strem筛选出年龄大于18居住在广州的人并且如果经过筛选后超过3个人那么只打印出这前人的名字
         */
        list.stream()
            .filter( Person -> Person.age>18 ) //返回岁数大于18的
            .filter( Person -> "广东".equals(Person.address) ) //返回住在广东的
            .map( Person -> Person.name ) //提取出他们的名字
            .limit(3) //截取前3条数据
            .forEach(Person -> System.out.println(Person) ); //将过来完的Person打印出来,注意:只能够迭代一次,迭代完流会关闭,即不能再做流操作

    }

}

class Person{
    String name;
    int age;
    String address;
    Person(String name, int age, String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }
}

Stream接口方法

boolean allMatch(Predicate<? super T> predicate)
    Returns whether all elements of this stream match the provided predicate. 

boolean anyMatch(Predicate<? super T> predicate)
    Returns whether any elements of this stream match the provided predicate. 

static <T> Stream.Builder<T> builder()
    Returns a builder for a Stream. 

<R,A> R collect(Collector<? super T,A,R> collector)
    Performs a mutable reduction operation on the elements of this stream using a Collector. 

<R> R collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator,            BiConsumer<R,R> combiner)
    Performs a mutable reduction operation on the elements of this stream. 

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
    Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream. 

long count()
    Returns the count of elements in this stream. 

Stream<T> distinct()
    Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream. 

static <T> Stream<T> empty()
    Returns an empty sequential Stream. 

Stream<T> filter(Predicate<? super T> predicate)
    Returns a stream consisting of the elements of this stream that match the given predicate. 

Optional<T> findAny()
    Returns an Optional describing some element of the stream, or an empty Optional if the stream is empty. 

Optional<T> findFirst()
    Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty. 

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
    Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. 

DoubleStream flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)
    Returns an DoubleStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. 

IntStream flatMapToInt(Function<? super T,? extends IntStream> mapper)
    Returns an IntStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. 

LongStream flatMapToLong(Function<? super T,? extends LongStream> mapper)
    Returns an LongStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. 

void forEach(Consumer<? super T> action)
    Performs an action for each element of this stream. 

void forEachOrdered(Consumer<? super T> action)
    Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order. 

static <T> Stream<T> generate(Supplier<T> s)
    Returns an infinite sequential unordered stream where each element is generated by the provided Supplier. 

static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
    Returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed)), etc. 

Stream<T> limit(long maxSize)
    Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length. 

<R> Stream<R> map(Function<? super T,? extends R> mapper)
    Returns a stream consisting of the results of applying the given function to the elements of this stream. 

DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)
    Returns a DoubleStream consisting of the results of applying the given function to the elements of this stream. 

IntStream mapToInt(ToIntFunction<? super T> mapper)
    Returns an IntStream consisting of the results of applying the given function to        the elements of this stream. 

LongStream mapToLong(ToLongFunction<? super T> mapper)
    Returns a LongStream consisting of the results of applying the given function to the elements of this stream. 

Optional<T> max(Comparator<? super T> comparator)
    Returns the maximum element of this stream according to the provided Comparator. 

Optional<T> min(Comparator<? super T> comparator)
    Returns the minimum element of this stream according to the provided Comparator. 

boolean noneMatch(Predicate<? super T> predicate)
    Returns whether no elements of this stream match the provided predicate. 

static <T> Stream<T> of(T... values)
    Returns a sequential ordered stream whose elements are the specified values. 

static <T> Stream<T> of(T t)
    Returns a sequential Stream containing a single element. 

Stream<T> peek(Consumer<? super T> action)
    Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream. 

Optional<T> reduce(BinaryOperator<T> accumulator)
    Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any. 

T reduce(T identity, BinaryOperator<T> accumulator)
    Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. 

<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
    Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions. 

Stream<T> skip(long n)
    Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream. 

Stream<T> sorted()
    Returns a stream consisting of the elements of this stream, sorted according to natural order. 

Stream<T> sorted(Comparator<? super T> comparator)
    Returns a stream consisting of the elements of this stream, sorted according to the provided Comparator. 

Object[] toArray()
    Returns an array containing the elements of this stream. 

<A> A[] toArray(IntFunction<A[]> generator)
    Returns an array containing the elements of this stream, using the provided generator function to allocate the returned array, as well as any additional arrays that might be required for a partitioned execution or for resizing. 

构建流的方法

//方法1:从容器中获取
//Collection.stream();

//方法2:使用Stream接口静态方法of方法获取
Stream<String> s = Stream.of("java","java7","java8","java9");

//方法3:使用数组获取
int[] arr = {1,2,3,4,5};
IntStream i = (IntStream)Arrays.stream(arr);
System.out.println( i.sum() ); //15

//方法4:从io流中获取
Stream<String> lines = Files.lines(Paths.get("D:\\", "123.txt"));
lines.forEach( str -> System.out.println(str) ); //打印文件中的内容
时间: 2024-10-14 23:11:37

学了忘忘了看之Java8的相关文章

设计模式看了又忘,忘了又看?

文章首发:设计模式看了又忘,忘了又看? 设计模式收藏这篇就够了 耗时了 5 个月,终于把设计模式一整个系列写完.其实设计模式这一系列文章网上已经有很多非常好.非常优秀的文章,为什么要写呢? 一方面是为了学得更扎实,印象中设计模式学习了 2 遍,记得牢的基本就那几个众所周知的,反思前面 2 次学习过程,缺少了思考的过程,没有把知识消化掉转化成自己的,就像动物一样,吃进去的东西没有消化只能排出. 另一方面是利用这个学习过程,学会把知识用文字表达出来,也把这份知识分享给各位同道中人. 没有期望说这系列

Android开发者:我学了就忘怎么办?

我们在学习的时候,多多少少都会遇到这么一个问题: "学了就忘" 之前也聊过这个问题,在我看来,这个问题是个共性问题,尤其初学者,更是不知所措,倍受打击,那么,为啥会学了就忘呢? 我根据自己的学习经验,大致总结以下三点原因: 知识没有用起来 没有及时复习 没有反馈输出 当然,导致我们学了就忘的原因不止如此,而且根据每个人的学习状况不同,可能远远不止如此,但是正如这个问题是个共性问题一样,我们在这里只说普遍性原因,可能很多人会因为出现上面三个原因导致学习效果不理想. 在此之前,你可能听过别

学计算机的如果你有耐心看下去,我敢保证这绝对是一种收获

大师提醒: 计算机专业不是学编程,而是懂得计算机的工作原理,以及和计算机相关的学科技术.一个高手不必懂得编程,coder是最底层的人物,最重要的是思想,解决问题的思想.对计算机专业的学生来说,英语和数学也是最重要的.编程不用于实际,编得最好也是花哨,毫无意义.对于初学者来说,应该懂得更多的why 原理,而不是更多的how,那是工作后的事情. 每一计算机学者都应该有自己的思想,不要跟着别人走,不要看着别人用什么新技术作出什么来的时候,你就心动了,也就想马上学这门技术.而是有自己的学习思路,和自己学

学了忘忘了看之Java多线程

Java多线程 什么是线程? 线程是相对于进程而言的,通常在计算机中,一个程序就是一个进程,而一个进程中可以有一个或多个的进程来完成该程序相关的功能. 举个不是很恰当的例子:例如乐队表演是一个进程,那么主唱和鼓手和和声等都可以理解为一个线程,他们共同来完成演奏一首曲子的工作. 什么是线程的并行和并发? 并行:指的是在同一台机器上,多个CPU同时执行同一段功能代码来完成功能: 并发:指的是在同一台机器上,CPU利用调度算法,以超高的速度切换进程来执行同一段代码来完成功能(让人感觉和并行一样): 理

学计算机的值得一看的文章,跟帖也很有水平啊

转自http://blog.csdn.net/Xviewee/article/details/1606247 回复CSDN和KAOYAN诸位网友的几点看法,(为避免吵架,郑重声明,本人不是高手,只是有感而发的一点个人陋见,欢迎指正,事先感谢): 就我自己的理解,谈谈我对读研和软件学院的看法,不妥之处一笑了之即可. 如果你有实际开发工作经验,感觉自己的水平和实力进入了一个高原期,迫切需要从理论上提高,那么计算机学院是唯一选择.因为计算机学院才能让你在理论上更上一层楼.软件学院从教学计划上就没有

学妹来实习,看我如何步步为营!

1. 每年暑假都会有许多大学生出来找实习.程序员们常常对此怀有某种期待——万一来一个长得乖的小妹,那无疑是给整个夏天带来了甜爽的清凉! 奈何天公不作美,从来就没有送来这样一个林妹妹!纵然年年来的实习生那么多,只可惜基本上都是抠脚大汉.即便偶尔撞到一两个女生,多半也是长得歪! 要说猥琐大叔的世界,哥不懂——管你一米五三两百多斤,管你脸大鼻塌眼小肤黑——那几个老杆子都会弹冠相庆.日日殷勤. 我总觉得这一定是一种病,也许是电脑辐射损伤了大脑皮层的某些反射区,才让他们变得不辩牛马.人畜不分. 每当肥鼠强

学技术,该怎么看书

要想学习一门计算机技术,看书自然是少不了的.但是很大一部分人却不知道该看什么书,又该怎么样去看.当然,这里所说的"书"并不是打印在纸上并装订成册的狭义书籍,而是包括传统书籍,视频,电子文档在内的广义书籍,或者称其为"文献"更为恰当,因为"文献"的定义就是一切记录知识的载体. 我把技术书籍分为四类: 第一类是入门型,一般的"快速入门"."从入门到精通".课本和大部分视频教程都属此范围:这类书的特点是讲解详细,

html5学得好不好,看掌握多少标签

html5学得好不好,看掌握多少标签 已回复 会员ID:wi701329 保密 62岁 时间:2016-06-28 06:52:49 html5你了解了多少?如果你还是入门阶段的话,或者还是一知半解的话 ,那么我们专门为你们收集的html5常用的标签大全对你就很有帮助了,你需要了解了html5有哪些标签你才能够更好的.驾驭html5这门火热而又充 满神秘的语言技术.下面是一些常用的html5标签.按字母顺序排列的标签列表 ?4: 指示在 HTML 4.01 中定义了该元素 ?5: 指示在 HTM

偷Microsoft师学MFC艺:且看C++如何支持反射

如果你问一个IT人士"C++如何实现类似Java的反射?",结果会怎样呢?~!@#¥%--&*,估计大部分人都会要稍微思考了一下,或者直接说"C++根本就不支持反射的呀!". 是的,C++语言本身是不支持反射的,但实际应用中总是会有将对象序列化的需求,总不可能C++不支持,我们就不用C++了,既然发明C++的大师们没有考虑这个,那我们只有自己动手了,毛主席说过"自己动手,丰衣足食"! 天生限制 C++语言本身不支持反射机制,但C++对象总