java 8 好用的特性

来源:互联网 发布:红辣椒与盗梦空间知乎 编辑:程序博客网 时间:2024/06/06 00:56
1.default   :实现面向接口编程
以前在使用java编程的时候,如果想复用某些特定实现方法,似乎只有通过继承或者委托来实现,但是由于java中又只能单继承,如果使用继承就会导致难以扩展,使用委托有会导致某些本应是继承关系的类变得模糊。

现在可以在接口中通过 default 关键字 就可以在接口中完成方法的实现了。

例子:

public interface TestDefault {    public int getSum();    default String getDescribe(){        return "Default description";    }}
这样就可以愉快的使用面向接口编程了。


2. Lambda 表达式  让你的代码更加简洁
比如在此之前写一个排序方法:
@Test    public void testSort(){        List<Integer> needSortNum = Arrays.asList(1,3,9,0,2,5,7);        Collections.sort(needSortNum, new Comparator<Integer>() {            @Override            public int compare(Integer a, Integer b) {                return b.compareTo(a);            }        });        System.out.println(needSortNum);    }

通过使用Lambda 表达式(->)之后就可以极大的简化代码了
首先需要定义一抽象类型的接口方法,例如jdk的自带实现

@FunctionalInterfacepublic interface Comparator<T> {int compare(T o1, T o2);}

注:上述代码只是截取的了该方法中的一部分
这样我们就可以通过Lambda 表达式来简化我们的代码,如下:

@Test    public void testSort(){        List<Integer> needSortNum = Arrays.asList(1,3,9,0,2,5,7);        Collections.sort(needSortNum,(a,b)->a.compareTo(b));        System.out.println(needSortNum);    }

解释:
(a,b)->a.compareTo(b)
其中  ->  表达式的左边为输入参数    右边为返回值
@FunctionInterface:如果发现该接口有多于一个抽象方法就会报错,用于让编译器帮助你语法检查。不带也没有问题。


3.方法的引用(::表达式):让你的代码更加灵活
例子:
首先定义一个测试对象,待会来引用该对象的方法

public class FunctionQuote {    private Integer money;    public FunctionQuote(){}    public FunctionQuote(int money){        this.money=money;    }    public void print(){        System.out.println("routine function");    }    public static void staticPrint(){        System.out.println("static function");    }}

a.对静态方法的引用
a1.首先定义一个函数接口

@FunctionalInterfacepublic interface FunctionInterface {    void print();}
a2.编写测试类

public class TestFunctionQuote {    @Test    public void testQuote(){        FunctionInterface functionInterface=FunctionQuote::staticPrint;        functionInterface.print();    }}
b.对非静态方法的引用


public class TestFunctionQuote {    @Test    public void testQuote(){        FunctionQuote functionQuote=new FunctionQuote();        FunctionInterface functionInterface=functionQuote::print;        functionInterface.print();    }}

c.对构造方法的引用
c1.编写函数接口

@FunctionalInterfacepublic interface CFunctionInterface<T>{    T createObj();}

c2.编写测试类

@Test    public void testQuote(){        CFunctionInterface<FunctionQuote> factory = FunctionQuote::new;        FunctionQuote obj=factory.createObj();    }
4.访问接口的默认方法
a.Function
有一个参数并返回一个结果,同时实现了可以和其他函数组合的默认方法,定义如下:
@FunctionalInterfacepublic interface Function<T, R> {    R apply(T t);    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {        Objects.requireNonNull(before);        return (V v) -> apply(before.apply(v));    }    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {        Objects.requireNonNull(after);        return (T t) -> after.apply(apply(t));    }    static <T> Function<T, T> identity() {        return t -> t;    }}
用法例子:
public class TestFunction {    @Test    public void testQuote(){        Function<String,String> printStr1=this::firstPrint;        Function<String,String> printStr2=printStr1.andThen(this::secondPrint);        printStr1.apply("hello world111");        System.out.println("--------------------------");        printStr2.apply("hello world222");    }    public String firstPrint(String s){        System.out.println(s+" fisrt print");        return s;    }    public String secondPrint(String s){        System.out.println(s+" second print");        return s;    }}

b.supplier
和Function接口区别不大,返回一个任意泛型的值,和Function接口的区别在于其方法接口没有参数输入,也就是0输入,1输出
定义

@FunctionalInterfacepublic interface Supplier<T> {    T get();}
例子

public class TestSupplier {    @Test    public void testQuote(){        Supplier<Integer> supplier=this::getMoney;        System.out.println(supplier.get());    }    public int getMoney(){        return 10000000;    }}

c.Consumer
顾名思义,也就是消费的意思
定义

@FunctionalInterfacepublic interface Consumer<T> {    void accept(T t);    default Consumer<T> andThen(Consumer<? super T> after) {        Objects.requireNonNull(after);        return (T t) -> { accept(t); after.accept(t); };    }}

例子

@Test    public void testQuote(){        Consumer<Integer> consumer1=(p) -> System.out.println("first:"+p);        Consumer<Integer> consumer2=consumer1.andThen((p)->System.out.println("second:"+p));        consumer1.accept(1);        System.out.println("--------------------");        consumer2.accept(2);    }

d.stream
定义:由于这个接口功能比较强大,同时代码比较长,有兴趣的可以在JDK中查看定义,此接口增强了集合类的操作,同时也可以让代码更加简洁
d1.filter方法
定义
Stream<T> filter(Predicate<? super T> predicate);
例子

public class TestSupplier {    @Test    public void testQuote(){        List<String> testList=createTestObj();        testList.stream().filter((str)->str.contains("123")).forEach(this::print);    }    private List<String> createTestObj(){        return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");    }    private void print(String str){        System.out.print(str+" ");    }}

d2.sorted方法
该方法有两个定义如下:

Stream<T> sorted();Stream<T> sorted(Comparator<? super T> comparator);
如果使用sorted()则使用默认的排序规则,或者传入一个指定的规则
例子:
public class TestSupplier {    @Test    public void testQuote(){        List<String> testList=createTestObj();        testList.stream().sorted((a,b)->b.compareTo(a)).forEach(this::print);    }    private List<String> createTestObj(){        return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");    }    private void print(String str){        System.out.print(str+" ");    }}

d3.map
方法的定义
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
作用:根据指定的Function接口将集合中的元素转换成另一种形式
例子:将字符串转化为大写
public class TestSupplier {    @Test    public void testQuote(){        List<String> testList=createTestObj();        testList.stream().sorted((a,b)->b.compareTo(a)).map(String::toUpperCase).forEach(this::print);    }    private List<String> createTestObj(){        return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");    }    private void print(String str){        System.out.print(str+" ");    }}

d4:match方法
定义


 boolean anyMatch(Predicate<? super T> predicate); boolean allMatch(Predicate<? super T> predicate); boolean noneMatch(Predicate<? super T> predicate);

作用:检测指定的predicate是否匹配整个stream
anyMatch:只有stream中任意一个元素匹配就返回true
allMatch:只有stream中所有元素匹配才返回true
noneMatch:只有stream中没有一个匹配才返回true
@Test    public void testQuote(){        List<String> testList=createTestObj();        boolean anyStartsWithA = testList.stream().anyMatch((s) -> s.startsWith("a"));  //true        boolean allStartsWithA = testList.stream().allMatch((s) -> s.startsWith("a"));  //false        boolean noneStartsWithA = testList.stream().noneMatch((s) -> s.startsWith("a"));  //false    }    private List<String> createTestObj(){        return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");    }

d5:Count
用于返回stream中的元素数量,当然可以和filter一起使用
定义
long count();
例子
 @Test    public void testQuote(){        List<String> testList=createTestObj();        testList.stream().count();        testList.stream().filter((s)->s.startsWith("a"));    }    private List<String> createTestObj(){        return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");    }
d6:Reduce
作用:用于将stream中的某些元素通过指定的规则合并成一个
定义
T reduce(T identity, BinaryOperator<T> accumulator);Optional<T> reduce(BinaryOperator<T> accumulator);<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);

例子:

@Test    public void testQuote(){        List<String> testList=createTestObj();        Optional<String> reduced=testList.stream().reduce((a,b)-> a+"#"+b);        System.out.println(reduced.get());    }    private List<String> createTestObj(){        return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");    }
e:parallelStream
作用:并行处理的parallelStream,在某种情形下处理速度会大大高于stram,但是并非一定会快。
定义
default Stream<E> parallelStream() {        return StreamSupport.stream(spliterator(), true);    }

5.Map的增强操作
Map不支持stream,同时也定义了一些好用的特性
a.putIfAbsent
定义:

default V putIfAbsent(K key, V value) {        V v = get(key);        if (v == null) {            v = put(key, value);        }        return v;    }

作用:通过上述代码就可以,就可以很清楚的表明了其作用,也就是插入数据的时候不需要做存在性检测
b.computeIfPresent
定义:

default V computeIfPresent(K key,            BiFunction<? super K, ? super V, ? extends V> remappingFunction) {        Objects.requireNonNull(remappingFunction);        V oldValue;        if ((oldValue = get(key)) != null) {            V newValue = remappingFunction.apply(key, oldValue);            if (newValue != null) {                put(key, newValue);                return newValue;            } else {                remove(key);                return null;            }        } else {            return null;        }    }
作用:修改特定key对应的value值,该值的修改通过传入的key value共同决定
@Test    public void testQuote(){        Map<Integer, String> map = new HashMap<>();        for (int i = 0; i < 10; i++) {            map.putIfAbsent(i, "val" + i);        }        System.out.println(map.get(3));     //  val3        map.computeIfPresent(3, (key, val) -> val + key);        System.out.println(map.get(3));     //  val33    }

c.remove
定义

V remove(Object key);

例子:

default boolean remove(Object key, Object value) {Object curValue = get(key);if (!Objects.equals(curValue, value) ||(curValue == null && !containsKey(key))) {return false;}remove(key);return true;}

d.getOrDefault
定义:

default V getOrDefault(Object key, V defaultValue) {        V v;        return (((v = get(key)) != null) || containsKey(key))            ? v            : defaultValue;    }

e.merge
定义
default V merge(K key, V value,            BiFunction<? super V, ? super V, ? extends V> remappingFunction) {        Objects.requireNonNull(remappingFunction);        Objects.requireNonNull(value);        V oldValue = get(key);        V newValue = (oldValue == null) ? value :                   remappingFunction.apply(oldValue, value);        if(newValue == null) {            remove(key);        } else {            put(key, newValue);        }        return newValue;    }
作用:针对特定的key对value进行操作
例子:

@Test    public void testQuote(){        Map<Integer, String> map = new HashMap<>();        for (int i = 0; i < 10; i++) {            map.putIfAbsent(i, "val" + i);        }        map.get(9);     //val        map.merge(9, "addval", (value, addValue) -> value+addValue);        map.get(9);     //val9addval    }







原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀孕八个月不想要怎么办 怀孕八个月不想要了怎么办 八个月宝宝拉肚子拉水怎么办 八个月的宝宝拉肚子怎么办 八个月发烧38度怎么办 孩子特别调皮好动该怎么办 孩子有好动症该怎么办 在幼儿园好动的孩子该怎么办 18个月宝宝上火怎么办 打孩子越打上瘾怎么办 八个月不想要了怎么办 胎儿心脏畸形肺动脉瓣闭锁怎么办 小孩爱动怎么办补什么 初中孩子下午上课总犯困怎么办 孩子上课精神不集中怎么办 孩子玩兴奋了就打人怎么办 婴儿兴奋白天不睡觉怎么办 小孩读书精神不集中怎么办 小孩上课精神不集中怎么办 小孩学习精神不集中怎么办 孩子暑假天天看电视不出门怎么办 七个月宝宝缺铁怎么办 天天运动为什么还便秘怎么办 小孩学习注意力不集中怎么办 8个月宝贝太好动怎么办 学生在校受伤家长该怎么办 多动症小孩爱动手指怎么办 孩子大了不听话该怎么办 流产后吹了风怎么办 怀孕1周内喝酒了怎么办 怀孕6周喝酒了怎么办 怀孕后喝了酒怎么办 不知道怀孕喝酒了怎么办 不知道怀孕了喝酒了怎么办 怀孕5天喝酒了怎么办 打孩子耳光后脸肿了怎么办 老师说上课不专心怎么办 孩子不专心好动马虎怎么办 学生上课不认真听讲怎么办 一年级孩子上课不注意听讲怎么办 一年级孩子上课说话不听课怎么办