Java中lambda表达式去重_JAVA8中Lambda和Stream
Java8于2014年3月份發(fā)布,其主要更新的特性有:函數(shù)式接口、Lambda 表達式、集合的流式操作、注解的更新、安全性的增強、IO\NIO 的改進、完善的全球化功能等,本文將介紹Lambda表達式與集合流試操作。
函數(shù)式接口
Java8引入的一個重要的思想就是函數(shù)式編程。 提到函數(shù)式,必須提到函數(shù)式接口。在Java8中對函數(shù)式接口的注解是@FunctionalInterface,任何一個只有一個抽象方法的接口都默認為是函數(shù)式接口,@FunctionalInterface注解是非必須的。如果在一個接口上加上該注解,那么這個接口就只能有一個抽象方法。如下
@FunctionalInterface
public interface TestInterface { void test(); }
也可以省略注解
public interface TestInterface { void test(); }
幾種常見的函數(shù)式接口比如說Function 支持傳入一個參數(shù)T并且返回R;
Predicate 傳入一個參數(shù)T返回一個boolean類型等等。
接口
參數(shù)
返回類型
Function
T
R
Predicate
T
boolean
Supplier
None
T
UnaryOperator
T
T
Consumer
T
void
BinaryOperator
(T, T)
T
Lambda
我們可以用Lambda表達式來實例化函數(shù)式接口,避免了內(nèi)部類冗余的代碼。
Lambda表達式的組成
Lambda表達式有多種形式,總結(jié)來說不外乎三部分組成:第一部分為一個括號內(nèi)用逗號分隔的形式參數(shù),參數(shù)是函數(shù)式接口里面方法的參數(shù),參數(shù)中可以指定類型,也可以省略類型(如果是單個參數(shù)的情況下括號可以省略,無參或者多個參數(shù)則不能省略括號);第二部分為一個箭頭符號:-> 是lambda的運算符;第三部分為方法體,可以是表達式和代碼塊。如下
TestInterface t = () -> System.out.println("lambda");
如果有入?yún)?#xff0c;第三部分是代碼塊,而且實現(xiàn)的接口有返回值的時候需要加上{}且要把結(jié)果return
public interface LongToInt { int toInt(Long i); }
LongToInt lti = i -> {
if(i != null){
return i.intValue();
} else return 0;
};
在Java8以前要想實例化接口使用匿名內(nèi)部類來處理,代碼顯得啰嗦而不易讀
new TestInterface(){
public void test() {
System.out.println("lambda");
}
}.test();
使用lambda表達式后就可以簡化成一行代碼
((TestInterface)() -> System.out.println("lambda")).test();
Lamdba中的方法引用
如果方法體只是簡單的函數(shù)引用則可以直接使用 :: 引用,更大程度上簡化我們的代碼。Java8中的 :: 符號表示:符號左邊的對象(List res),調(diào)用符號右邊的方法(add()),參數(shù)即為lamdba表達式的參數(shù)(Integer)。
List res = Lists.newArrayList();
ints.forEach(res :: add);
Stream
java8中引用stream可以對集合進行過濾、排序、映射等操作。
生成Stream
Java8的stream分為兩種,即并行和串行。可以通過Collection.parallelStream()生成一個并行流,可以通過Collection.stream()生成一個串行流(默認的stream開啟的是串行流)。Stream通過StreamSupport.stream(Spliterator spliterator, boolean parallel)方法中的parallel來判斷是否生成并行流。
default Stream stream() {return StreamSupport.stream(spliterator(), false);}
default Stream parallelStream() {return StreamSupport.stream(spliterator(), true);}
我們還可以將生成的stream通過stream.parallel()或stream.sequential()轉(zhuǎn)換成并行或者串行。
通過方法名我們不難理解,串行流在一個線程依次執(zhí)行,而并行流則是在多個線程同時執(zhí)行。并行流的執(zhí)行效率遠遠大于串行流。
Stream應(yīng)用
一般在Java中使用stream有三步:第一步生成stream;第二步對stream進行轉(zhuǎn)換;第三步聚合操作得到想要的結(jié)果。
Stream的中間轉(zhuǎn)換操作
distinct: 對stream中的元素進行去重操作。
filter: 對stream中包含的元素使用給定的過濾函數(shù)進行過濾操作,而filter方法傳的參數(shù)就是Predicate實例化,即可以. 使用上面提到的lambda表達式(新的stream中只包含Predicate中判定為true的元素)。
map: 對stream中包含的元素使用給定的轉(zhuǎn)換函數(shù)進行轉(zhuǎn)換操作.這個方法有三個引申方法,分別是:mapToInt,mapToLong和mapToDouble,在map中執(zhí)行轉(zhuǎn)換函數(shù),再轉(zhuǎn)換新的的stream元素為Integer, Long, Double類型。轉(zhuǎn)換函數(shù)類型為Function,用lambda表達式比較方便。
flatMap:會把要求Function的返回值是stream即在map里面用stream的子元素再生成一個stream,把所有的子元素生成的stream壓縮成一個stream。
boxed: 將LongStream、IntStream、DoubleStream轉(zhuǎn)換成對應(yīng)類型的Stream。
limit: 對一個stream進行截斷操作,獲取其前n個元素,如果原stream中包含的元素個數(shù)小于n,那就獲取其所有的元素;
skip: 返回一個丟棄原stream的前n個元素后剩下元素組成的新stream,如果原stream中包含的元素個數(shù)小于n,那么返回空stream;
Stream的聚合操作
collect: 將stream元素收集起來,可以通過Collectors.toList()實現(xiàn)將stream轉(zhuǎn)換為List的操作。
count: 得到stream的元素個數(shù)。
findFirst: 得到第一個元素。
max: 需要自定義一個Comparator來比較元素的大小,返回最大值。
min: 需要自定義一個Comparator來比較元素的大小,返回最小值。
allMatch: 判斷元素是否全部符合Predicate標準。
anyMatch: 判斷元素是否有一個或者多個符合Predicate標準。
noneMatch: 判斷元素是否都不符合Predicate標準。
List strList = Lists.newArrayList("11 ", "213 ", " 11", "23", "145", "15 ", "2 ", " 3", "");
List ints = Lists.partition(strList, 3).stream().flatMapToInt(strs -> strs.stream().filter(str -> str != null && !Objects.equals(str, "")).mapToInt(str -> Integer.valueOf(str.trim()))).distinct().limit(5).skip(3).boxed().collect(Collectors.toList());
上面的例子是把一個List,先通過Guava Lists將該list按每組3個拆分生成List>再轉(zhuǎn)換為Stream>,再flatMapToInt,在map里面再將list轉(zhuǎn)換為Stream,過濾掉空字符串和null,再mapToInt去重,取前5個,再丟棄前三個元素,再轉(zhuǎn)換成一個List。
注:所有的聚合操作、foreach操作都會把stream關(guān)閉,如果一個stream被關(guān)閉后,不能再次對stream進行任何操作。
總結(jié)
以上是生活随笔為你收集整理的Java中lambda表达式去重_JAVA8中Lambda和Stream的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java黑色_java-透明的黑色圆圈
- 下一篇: java字段不序列化注解_@Transi