JDK8 知識點日常積累
目錄
1. Consumer函數式接口的用法,通過consumer,可以進行函數式接口寫法
2.* @FunctionalInterface 函數式接口的使用
3. 函數式接口的使用實例,JDK中的Predicate接口
一:小方法積累
【小知識點積累】
1. Stream.Of(T... value),該接口將直接返回value值的流對象,可以利用進行處理,ex:Stream.Of("A","A","A","A","A","A","A").forEach();
2. List集合的removeIf(),ex: list == "A","A","A","A","A","A"; list.removeIf(s -> s.equse("B")); 通過該表達式,可以將list中等於B的字符刪除掉。
二:重點知識點積累
【中高知識點積累】
1. Consumer函數式接口的用法,通過consumer,可以進行函數式接口寫法
ex:
/**
* @author hengtao.wu
* Consumer 爲函數式接口體現,通過該接口,可以完成將特定值進行處理的實現。
* 該接口中核心接口有兩個,
* ① accept,接受並處理傳參
* ② andThen,執行完accept之後繼續進行的操作
* @Date 2019/10/28 10:05
**/
public class ConsumerTest {
public static void main(String[] args) {
//lambda之前的寫法,通過foreach的方式,將consumer創建實例並執行方法的方式作爲參數,進行處理list中的元素
/*List<String> list = Arrays.asList("a","b","c","d","e");
List<String> result = new ArrayList<>();
list.forEach(new java.util.function.Consumer<String>() {
@Override
public void accept(String s) {
if(s.equals("a") || s.equals("c")) {
result.add(s);
}
}
});
System.out.println(result);*/
//other寫法
List<String> result = new ArrayList<>();
Consumer<String> consumer = s -> {
if(s.equals("a") || s.equals("c")) {
result.add(s);
}
};
//執行accept之後繼續處理的方法.
consumer.andThen(s -> {
result.removeIf(ss -> ss.equals("a"));
});
Stream.of("a",
"b",
"c",
"d",
"e").forEach(consumer);
System.out.println(result.toString());
}
//對比lambda表達式,consumer就顯得比較冗餘了。lambda表達式,會更簡單
Stream.of("a",
"b",
"c",
"d",
"e").forEach(s -> {
if(s.equals("c")) {
result.add(s);
}
});
}
2.* @FunctionalInterface 函數式接口的使用
說明:該註解的意思是,將該接口生命爲函數式接口,可以通過將匿名類/lambda表達式作爲參數,進行方法傳遞,並且,該接口中必須只有一個實現方法。也就是說,任何使用匿名類/lambda進行參數傳遞時,都是默認實現了該方法進行實例化的。
例如:
@FunctionalInterface
public interface WorkService<T> {
void doSomeThing(T t);
}
****************************************
public class FunctionalInterfaceTest {
public static void test(WorkService workService) {
workService.doSomeThing("aaa");
}
public static void main(String[] args) {
//此時調用test方法時,將lambda表達式傳入,默認就是實現了接口中的dosomething方法。
test((s) -> {System.out.println(s + "wahaha");});
//此時,實例化WorkService對象是,直接實現該接口中的doSomeThing方法,就完成了實例化。
WorkService<String> w = s -> {if(s.equals("a")) {
System.out.println("OK");
}};
w.doSomeThing("bb");
}
}
3. 函數式接口的使用實例,JDK中的Predicate接口
public class PredicateTest {
public static void main(String[] args) {
List<Integer> num = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
checkNum(num, new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer%2 == 0;
}
});
//通過匿名內部類與通過lambda表達式所達到的效果是一致的,都是將函數作爲參數,進行方法傳遞,從而達到實例化接口的作用。
checkNum(num, n -> n%2 == 0);
}
public static void checkNum(List<Integer> list, Predicate<Integer> predicate) {
list.forEach(integer -> {
// 此時的test方法,就是參數傳遞時,所表達的方法。
if(predicate.test(integer)) {
System.out.println(integer);
}
});
}
}
4. 四種常用函數式接口使用總結
/**
*四種常用接口簡單舉例總結
*/
public static void main(String[] args) {
//1. consumer接口,有參,無返回類型
List<String> list = Arrays.asList("a","a","a","a","a","a","a");
consumerTest(list, s -> {if("a".equals(s)) {System.out.println("執行刪除操作!");}});
//2. 常用接口Supplier,無參 有返回值的函數式接口
Supptest(() -> {
String s = "aa";
return s + "bb";
});
//3. 常用接口Function,有參 有返回值的函數式接口
funcTest(100, num -> String.valueOf(num + 150));
//4. predicate接口,有參,有返回類型,參數爲泛型,返回類型爲固定Boolean型,主要用作驗證、過濾等操作。
List<String> result = predicateTest(list, s -> "b".equals(s));
}
/**
*1. Consumer, 有參,無返回類型,主要進行一些判斷後操作。參數類型爲泛型
*/
public static void consumerTest(List<String> list, Consumer<String> consumer) {
list.forEach(consumer);
}
/**
* 2. 常用接口Supplier,無參 有返回值的函數式接口,返回類型爲泛型
*/
public static String Supptest(Supplier<String> supp) {
return supp.get();
}
/**
*3. 常用接口Function,有參 有返回值的函數式接口,泛型定義參數類型與返回類型
*/
public static String funcTest(Integer num, Function<Integer, String> function) {
return function.apply(num);
}
/**
*4. predicate接口,有參,有返回值,返回值爲固定Boolean類型,參數爲泛型。主要用作驗證、過濾等操作。
*/
public static List<String> predicateTest(List<String> list, Predicate<String> predicate) {
List<String> result = new ArrayList<>();
list.forEach(s -> {
if(predicate.test(s)) {
result.add(s);
}
});
return result;
}
5. 方法引用
public static void main(String[] args) {
/**
* 方法引用:
* 說明:用引用方法的方式,代替lambda表達式。
* 核心:① 被引用的方法參數、返回類型必須與函數式接口的抽象方法一致;
* ② 調用時,直接調用接口實例對象調用抽象方法即可直接調用被引用的方法
* 總結:其實就是通過引用實例方法的方式,實例化函數式接口,並實現該接口中的抽象方法。
* 換言之就是用引用別的方法的方式,替代了lambda表達式的寫法
* 拓展:還有數組引用、構造器引用等方式。
*/
Boolean result = null;
//old way
MethodInterface<String, String, Boolean> methodInterfaceOld = (s1, s2) -> {
if(s1.equals(s2)) {
return true;
}else {
return false;
}
};
result = methodInterfaceOld.equalss("a","b");
//方法引用---1. 靜態方法引用 類名::靜態方法
// new way 其中equals()中的方法其實也是if else判斷
MethodInterface<String, String, Boolean> methodInterfaceNew1 = StaticMethod::equals;
result = methodInterfaceNew1.equalss("a","b");
// old way === new way 一樣的意思
//方法引用---2. 實例對象方法引用 對象::方法
Person person = new Person();
MethodInterface<String, String, Boolean> methodInterfaceNew2 = person::equals;
result = methodInterfaceNew2.equalss("s1","s2");
}
6. lambda與stream組合操作集合方法合輯
public static void main(String[] args) {
List<Person> javaProgrammers = getList2();
List<Person> phpProgrammers = getList1();
//1. 通過forEach改變集合中每個對象中的薪資值
javaProgrammers.forEach(j -> j.setSalary(j.getSalary() + 100));
//2. filter過濾器,過濾薪資超過1400$的。 filter中的參數值爲pridicate函數式接口,可以爲pridicate實例,或者直接是lambda表達式
phpProgrammers.stream().filter(p -> p.getSalary() > 1400)
.forEach(System.out::println);
//2.1 多過濾器,同時將年齡>25 ,薪資>1400的人員篩選出來並打印
Predicate<Person> ageFilter = p -> p.getAge() > 25;
Predicate<Person> salaryFilter = p -> p.getSalary() > 1400;
javaProgrammers.stream().filter(ageFilter)
.filter(salaryFilter)
.forEach(System.out::println);
//3. limit限制結果個數用法
javaProgrammers.stream().filter(ageFilter).limit(3).forEach(System.out::println);
//4. 排序,按照薪資大小排序
javaProgrammers.stream().sorted((j1, j2) -> j1.getSalary() - j2.getSalary()).forEach(System.out::println);
//5. min、max的用法,按照薪資排序,獲取最大/最小的值
javaProgrammers.stream().min((j1, j2) -> j1.getSalary() - j2.getSalary()).get();
//6. 利用map()方法進行操作
//6.1 將name拼接返回字符串
String result = javaProgrammers.stream().map(j -> j.getFirstName()).collect(Collectors.joining(";"));
//6.2 將name獲取,存在集合中
List<String> list = javaProgrammers.stream().map(j->j.getFirstName()).collect(Collectors.toList());
//6.3 並行map .sum 方法可被替換成其他,count/min/max/average/limit等...
int sum = javaProgrammers.stream().mapToInt(j->j.getSalary()).sum();
//6.4 還可以直接過去到IntSummaryStatistics對象,分別獲取sum/min/max等彙總數據
IntSummaryStatistics intSummaryStatistics = javaProgrammers.stream().mapToInt(j->j.getSalary()).summaryStatistics();
intSummaryStatistics.getSum();
}