java 8 好用的特性

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的自带实现

@FunctionalInterface
public 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.首先定义一个函数接口

@FunctionalInterface
public 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.编写函数接口

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

c2.编写测试类

@Test
    public void testQuote(){
        CFunctionInterface<FunctionQuote> factory = FunctionQuote::new;
        FunctionQuote obj=factory.createObj();
    }
4.访问接口的默认方法
a.Function
有一个参数并返回一个结果,同时实现了可以和其他函数组合的默认方法,定义如下:
@FunctionalInterface
public 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输出
定义

@FunctionalInterface
public 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
顾名思义,也就是消费的意思
定义

@FunctionalInterface
public 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
    }







  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值