Java-JDK8 新特性

Java-JDK8 新特性


<一>函数式接口

1.基础知识:

定义:有且只有一个抽象方法的接口
格式:(@FunctionalInterface 注释表明这是一个函数式接口)

@FunctionalInterface
public interface FI0 {
    public abstract void method();
}

抽象式接口一般作为方法的参数和返回值类型
接口当中的抽象方法public abstract可以省略

public interface MyFunctionalInterface {
	void myMethod();
}

2.使用方法

(1)调用show方法,方法的参数是一个接口,所以可以传递接口的实现类对象
(2)使用匿名内部类重写接口中的抽象方法

public static void main(String[] args) {
        show(new FI0Impl());
        ///调用show方法,方法的参数是一个接口,所以可以传递接口的实现类对象
        show(new FI0(){//使用匿名内部类重写接口中的抽象方法
            @Override
            public void method() {
                System.out.println("使用匿名内部类重写接口中的抽象方法");
            }
         }j
      }
   }

<二>使用Lambda表达式

使用Lambda表达式仅仅作为参数传递,仅仅把参数传递到showlog方法中,
只有满足条件时(等级是1):才会调用接口中的方法;
若不满足,则接口中的代码不会执行,不会存在性能的浪费。
注:必须是函数式接口才能使用Lambda表达式然使用 Lambda 表达式可以对某些接口进行简单的实现,但并不是所有的接口都可以使用 Lambda 表达式来实现。Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法。
Lambda表达式简化:

Lambda表达式写法

普通写法:

ReturnOneParam returnOneParam = (int a) -> {
    System.out.println("ReturnOneParam param:" + a);
    return 1;
};

简化写法:

 		//1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
        NoReturnMultiParam lamdba1 = (a, b) -> {
            System.out.println("简化参数类型");
        };
        lamdba1.method(1, 2);
//================================================================================
        //2.简化参数小括号,如果只有一个参数则可以省略参数小括号
        NoReturnOneParam lambda2 = a -> {
            System.out.println("简化参数小括号");
        };
        lambda2.method(1);
//================================================================================
        //3.简化方法体大括号,如果方法条只有一条语句,则可以省略方法体大括号
        NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
        lambda3.method();
//================================================================================
        //4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
        ReturnOneParam lambda4 = a -> a+3;
        System.out.println(lambda4.method(5));

<三>常用函数式接口

1.Supplier接口

java.util.function.Supplier<T>:包含一个无参方法 T get() ,用来获取一个泛型参数指定类型的对象数据。
Supplier<T> 接口被称为生产型接口,接口中get()方法会产生与指定接口泛型相同的类型的数据。

import java.util.function.Supplier;

public class Supplier0 {
    public static String YYY(Supplier<String> b){
      return b.get();
    }

    public static void main(String[] args) {
 调用前面定义的YYY方法,方法的参数Supplier是一个函数式接口,所以可以传递Lambda表达式
        String str=YYY(()->{
            return "嘤嘤嘤";
        });
        System.out.println(str);
    }
}

实例:

用Supplier接口,通过Lambda表达式求出int数组中的最大值(接口泛型使用Integer)

public class Demo02Test {
	//定一个方法,方法的参数传递Supplier,泛型使用Integer
	public static int getMax(Supplier<Integer> sup){
		return sup.get();
	}
public static void main(String[] args) {
	int arr[] = {2,3,4,52,333,23};
	//调用getMax方法,参数传递Lambda
	int maxNum = getMax(()>{
		//计算数组的最大值
		int max = arr[0];
		for(int i : arr){
			if(i>max){
				max = i;
			}
		}
		return max;
	});
	System.out.println(maxNum);
	}
}

2.Consumer接口

java.util.function.Consumer<T> 是消费型函数式接口,
accept 方法传递参数并消费(执行操作)

private static void consumeString(Consumer<String> function) {
	function.accept("Hello");
}

AndThen 方法:将两个Consumer接口连接起来

import java.util.function.Consumer;

public class AndThen0 {
    public static void A(String s, Consumer<String> s1,Consumer<String> s2,Consumer<String> s3){
        s1.andThen(s2).andThen(s3).accept(s);
    }

    public static void main(String[] args) {
        A("You Are A 666 Person!",(s)->{
            System.out.println(s.toUpperCase());
        },(s)->{
            System.out.println(s.toLowerCase());
        },(s)->{
            System.out.println(s.split("r")[0]);
        });
    }
}

上述结果为:
YOU ARE A 666 PERSON!
you are a 666 person!
You A

3.Predicate接口

java.util.function.Predicate<T> : 判断数据类型,并返回Boolean值
Predicate.and:等效于&&
Predicate.or:等效于||
Predicate.negate:等效于!
test :Predicate 接口中包含一个抽象方法:boolean test(T t) 用于条件判断的场景:

private static void method(Predicate<String> predicate) {
	boolean veryLong = predicate.test("HelloWorld");
	System.out.println("字符串很长吗:" + veryLong);
}
public static void main(String[] args) {
	method(s ‐> s.length() > 5);
}

4.Function接口

java.util.function.Function<T,R>:根据一个类型的数据得到另一个
andThen:进行组合操作(类似与Cunsumer方法中的andThen)

public static void main(String[] args) {
	String str = "赵丽颖,20";
	int age = getAgeNum(str, s ‐> s.split(",")[1],
	s ‐>Integer.parseInt(s),
	n ‐> n += 100);
	System.out.println(age);
}
private static int getAgeNum(String str, Function<String, String> one,
										Function<String, Integer> two,
										Function<Integer, Integer> three) {
		return one.andThen(two).andThen(three).apply(str);
	}

<四>Stream流

1.Steam流思想概况

采用队列化编程思想,将一系列步骤连接起来,将多个操作串联成管道。以工厂流水线的形式对数据逐步加个,不保留中间数据。

2.获取Stream流

(1)使用集合方法中的Stream

List<String> list = new ArrayList<>();
    Stream<String> stream1 = list.stream();
//===================================================
Set<String> set = new HashSet<>();
    Stream<String> stream2 = set.stream();
//===================================================
Collection<String> values = map.values();
    Stream<String> stream4 = values.stream();
//===================================================
Set<Map.Entry<String, String> entries = map.entrySet();
    Stream<Map.Entry<String, String>> stream5 = entries.stream();

(2)使用Stream方法中的Stream.of方法

Stream<Integer> stream6 = Stream.of(1, 2, 3, 4, 5);
//===================================================
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream7 = Stream.of(arr);
//===================================================
String[] arr2 = {"a","bb","嘤嘤嘤"};
Stream<String> stream8 = Stream.of(arr2);

3.常用方法

(1) forEach 方法:遍历出Stream流中的数据 (遍历之后不能继续调用Stream流中的其他方法)

Stream.forEach(name->Systeminfo.out.println(name));

(2) filter 方法:传递lambda表达式,对元素进行过滤

 public static void main(String args[]) {
        Stream<String> s=Stream.of("1","a","嘤嘤嘤","嘤嘤怪");
        Stream<String> s2=s.filter((String name)->{return name.startsWith("嘤");});//用s2接收
        s2.forEach(n-> System.out.println(n));//遍历
    }

(3) map 方法:将当前数据类型的数据转换成另一种数据类型

 Stream<String> s3=s.map((String str)->{return Integer.parseInt(s);});

===============================================================================================
(4) count 方法: long count():统计Stream流中元素的个数(类似于Collection中的size)

Stream<String> original = Stream.of("尼古拉斯赵四", "张三丰", "张四丰");
Stream<String> result = original.filter(s ‐> s.startsWith("张"));
System.out.println(result.count()); // 2

(5) limit 方法:Stream<T> limit(long maxSize) :截取前n个元素,并返回一个新的流

Stream<String> result = original.limit(2)//若有三个元素,输出时只显示前两个元素;;

(6) skip 方法:跳过前几个元素,如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流

Stream<String> result = original.skip(2)//若有三个元素,输出时只显示最后一个元素;

(7) concat 方法:将两个流合并为一个新的流静态方法

Stream<String> result = Stream.concat(streamA, streamB);

<五>方法引用

如果Lambda要表达的函数方案已经存在于某一个方法的实现中,那么可以用 “::” 来引用改方法作为Lambda的替代者。
(1)通过类名引用静态方法:

method(-666,Math::abs);

(2)通过super引用父类方法:
通过this引用本类的成员方法

public void beHappy() {
	marry(this::buyHouse);
}

类的构造器 类名称::new
数组的构造器引用

int[] array = initArray(10, int[]::new);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烂糊Java汤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值