文章作者:Tyan
博客:noahsnail.com
在Java應(yīng)用中進(jìn)行集合對象間的轉(zhuǎn)換是非常常見的事情贞奋,有時候在處理某些任務(wù)時選擇一種好的數(shù)據(jù)結(jié)構(gòu)往往會起到事半功倍的作用,因此熟悉每種數(shù)據(jù)結(jié)構(gòu)并知道其特點對于程序員來說是非常重要的滴某,而只知道這些是不夠的斯棒,有時候你需要一個Map來處理數(shù)據(jù),而此時你手中只有一個List室叉,此時知道如何將List轉(zhuǎn)為Map就非常重要了,而只知道for循環(huán)將List轉(zhuǎn)為Map這就太Low了匙隔,JDK1.8 吸收了許多函數(shù)式編程的思想,其中的lambda表達(dá)式不僅功能強(qiáng)大,而且減少了很多不必要的代碼,本文不是介紹lambda表達(dá)式的害驹,主要是利用lambda表達(dá)式進(jìn)行Java中結(jié)合的轉(zhuǎn)換,當(dāng)然lambda表達(dá)式的使用往往離不開JDK1.8 的stream類蛤育,本文主要使用***lambda表達(dá)式***和***stream類***來實現(xiàn)Java中集合的轉(zhuǎn)換宛官,也會涉及到利用stream對數(shù)據(jù)進(jìn)行的一些處理。
1.List To Map <==> Map To List
將List轉(zhuǎn)換為Map是Java中的常見操作瓦糕,例如我想知道某個對象是否已經(jīng)在List中底洗,此時就需要將List轉(zhuǎn)成Map,你總不會打算for循環(huán)一個個比吧咕娄!
@Data //lombok提供的注解亥揖,會自動添加getter和setter
public class Student {
private String id;
private String name;
private String info;
}
現(xiàn)在有一個所有學(xué)生信息的列表List<Student> list
和一個要新添加的學(xué)生Student studentNew
,在添加學(xué)生之前需要對新添加的學(xué)生信息studentNew
進(jìn)行判斷是否已經(jīng)在list
中谭胚,學(xué)生的唯一標(biāo)識是id徐块,不考慮其他,就是單純的用Java代碼判斷灾而,此時就需要將List轉(zhuǎn)為Map,代碼如下:
Map<String, Student> studentMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
if(studentMap.containsKey(studentNew.getId())) {
System.out.println("studentNew in map!");
}
將Map轉(zhuǎn)為List就非常簡單了:
List<Student> listValues = new ArrayList<Student>(studentMap.values()); //map values
List<String> listKeys = new ArrayList<String>(studentMap.keySet()); //map keys
2.List To Set <==> Set To List
List與Set之間的轉(zhuǎn)換就很容易了扳剿,Set To List:
Set<String> set = new HashSet<String>();
set.add("123");
set.add("456");
List<String> setToList = new ArrayList<String>(set); //Set To List
List To Set:
Set<String> listToSet = new HashSet<String>(listSet);
注:如果需要對List去重可以使用Set旁趟,這List To Set + Set To List
兩個操作可以將List中的重復(fù)元素去掉。這里用的是HashSet庇绽,如果需要一個有序的List锡搜,可以選擇TreeSet,TreeSet需要實現(xiàn)對象的Comparable接口瞧掺。
3.Array To List <==> List To Array
參考:Java中List與Array的轉(zhuǎn)換
注:對Array的許多操作都可以先將Array轉(zhuǎn)為List耕餐,然后再進(jìn)行需要的轉(zhuǎn)換再進(jìn)行處理,或轉(zhuǎn)為List后使用Stream提供的操作來進(jìn)行處理辟狈。
4.Map To Set <==> Set To Map
Map與Set之間的轉(zhuǎn)換也比較簡單肠缔,Map To Set:
Set<String> mapToSetKeys = new HashSet<String>(studentMap.keySet()); //map keys
Set<Student> mapToSetValues = new HashSet<Student>(studentMap.values()); //map values
Set To Map:
Map<String, Student> setToMap = mapToSetValues.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
5.List排序
要對List中的對象進(jìn)行排序以前非常麻煩夏跷,什么對象實現(xiàn)Comparable接口啊,寫一個StudentComparator實現(xiàn)Comparator接口呀明未,非常麻煩槽华,現(xiàn)在非常簡單一行代碼搞定(兩種方式):
list.sort(Comparator.comparing(Student::getName)); //按名字排序
list.sort((p1,p2) -> {
return p1.getName().toLowerCase().compareTo(p2.getName().toLowerCase());
});//lambda表達(dá)式
6.stream中的filter功能
filter功能主要是對集合中的元素進(jìn)行過濾,以List為例趟妥,找出名字叫Jack的學(xué)生:
List<Student> filterResult = list.stream().filter(p -> StringUtils.equals(p.getName(), "Jack")).collect(Collectors.toList());
filterResult.stream().forEach(p -> {
System.out.println(p.getName());
});
上面的代碼使用了stream的filter函數(shù)和forEach函數(shù)猫态,以后可以少寫for循環(huán)遍歷List了。filter的->
后面需要返回一個boolean值披摄。最好"Jack"寫前面亲雪,習(xí)慣。
filter會對List中的每個元素進(jìn)行處理疚膊。
7.stream中的map功能
給每個學(xué)生的名字后面加上個China:
List<Student> mapResult = list.stream().map(p -> {
p.setName(p.getName() + " China");
return p;
}).collect(Collectors.toList());
mapResult.stream().forEach(p -> {
System.out.println(p.getName());
});
map函數(shù)的主要功能是對List中的每個元素進(jìn)行處理并返回匆光,可以返回其它的數(shù)據(jù)類型,例如:
List<String> mapResult = list.stream().map(p -> {
p.setName(p.getName() + " China");
return p.getName();
}).collect(Collectors.toList());
mapResult.stream().forEach(p -> {
System.out.println(p);
});
8.filter和map結(jié)合起來用
找出名字為Jack的Student并在名字后面加上China:
List<Student> result = list.stream().filter(p -> StringUtils.equals("Jack", p.getName())).map(p -> {
p.setName(p.getName() + " China");
return p;
}).collect(Collectors.toList());
result.stream().forEach(p -> {
System.out.println(p.getName());
});