集合的嵌套用法
- 对于集合的嵌套用法,我们可以简单的化为三类,list嵌套list,list嵌套map,map嵌套map。
- 对于集合嵌套的赋值,我们采用由里向外赋值,对于取值相反,取值时由外向里。
1.list嵌套map
我们举map中有list的形式,即map的key为引用类型,value为list,可以写成
Map<String ,List<Person>> map =new HashMap<>();
-
前面说了我们赋值时由里向外,什么是由里向外呐,就是先对里边的list赋值,然后再将值传给map。
-
由于要给list赋值,而list用的是Person类型,即我们自己定义的类型,所以先new对象然后赋值。
//Person类 public class Person { private String name; private String unit; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUnit() { return unit; } public void setUnit(String unit) { this.unit = unit; } }
Person person = new Person(); Person person1 = new Person(); Person person2 = new Person(); Person person3 = new Person(); person.setName("sk"); person1.setName("sa"); person2.setName("sc"); person3.setName("ss"); person.setUnit("1层"); person1.setUnit("2层"); person2.setUnit("3层"); person3.setUnit("4层");
-
将每个person中都附上值之后,我们将person传给list
List<Person> list =new ArrayList<>(); List<Person> list1 =new ArrayList<>(); List<Person> list2 =new ArrayList<>(); List<Person> list3 =new ArrayList<>(); list.add(person); list1.add(person1); list2.add(person2); list3.add(person3);
-
将内层的值赋给list之后,我们就开始给map赋值。
map.put("一栋",list); map.put("二栋",list1); map.put("三栋",list2); map.put("四栋",list3);
-
这时我们的赋值操作就做完了,但是给map附上值之后,我们该怎么将各个值输出出来呐?还是像之前一样用Lambda表达式或者强化for循环给一次遍历出来吗?
-
提到这,我们就要讲一下嵌套的本质了,比如我们这里 map.put(“一栋”,list); list里边虽然存了好几个元素,但是对于map来说,key对应的就是多个value了吗?答案是否定的,对于集合我们可以知道,一个key只对应一个value,而且key不能重复。所以其实list也是一种引用数据类型,对于map来说,list就跟其他定义的引用数据类型一样,它只知道每个key对应一个value,value里边的可以是地址。
-
所以对于集合嵌套来说,其实取值就是相当于先将外层遍历,然后再对内层遍历。到这时其实思路就很明白了,为什么取值要由外往内,因为我们不知道里边有多少值,所以我们先取外边的,再将里边的遍历一遍。其实也相当于再用一遍遍历嵌套,
-
对于遍历我们常用的是Lamdba表达式,所以就我们用Lamdba表达式写这个。
map.forEach((keys,value)->{ System.out.println(keys); value.forEach((values)->{ System.out.println(" 住户"+values.getName()+"的住户层为"+values.getUnit()); }); });
-
对于map集合的遍历应该都知道是map.forEach(key,value)->{}。如果我们要输出map的话,可以直接在花括号中输出key和value。但是对于集合嵌套来说,如果直接输出value,很明显会输出一串地址,因为我们value中的是list集合,而list集合存放的是person 。
-
而要想将list中的值取出,我们可以在进行一次遍历。因为value中存放的是list。所以我们用value.forEach(values)->{}来取list的值。又由于list中洪范类型是Person类,所以我们输出的时候就可以value.getName()和 value.getUnit(),将值取出。到这我们就写完了。
2.Map嵌套Map
-
对于Map嵌套Map,我们其实写法也是一样,就是在Value中存放泛型为Map类型,Key中存放泛型。然后里边的Map再用泛型表示Key和Value。
-
先定义一个嵌套mapMap
Map<String ,Map<String ,String>> mapMap = new HashMap<>();
-
定义完之后我们要往里边存数据,就还需要在定义map 泛型往value里边存数据。
Map<String ,String > map1 = new HashMap<>(); Map<String ,String > map2 = new HashMap<>(); Map<String ,String > map3 = new HashMap<>(); map1.put("002","asd"); map2.put("003","qwe"); map3.put("004","aad");
-
value整好之后,我们就可以给mapMap存了,
mapMap.put("K1",map1); mapMap.put("K2",map2); mapMap.put("K3",map3);
-
这时赋值操作就完成了。接下来我们就要做取值,上面展示了用forEach做,下面我们用强化for循环做,注意的是这里也可以用forEach做,但是不能用普通for循环遍历map,因为map集合是无序的。
Set<String> keys = mapMap.keySet(); for(String k:keys){ System.out.println(k); Set<String> a = mapMap.get(k).keySet(); for(String b:a){ System.out.println(b+" "+mapMap.get(k).get(b)); } }
-
对于map集合用强化for循环遍历,我们要先定义一个set集合用来存放keySet()的key集合。然后对keyset遍历即可。
-
遍历外边一层很容易,可能用人不明白为什么在第二次强化for之前也要遍历,其实是因为第二次跟第一次一样,也需要一个set集合来存放里边的key值,毕竟嵌套的也是map集合,也需要遍历。而对于第二个k,其实就是第一个也就是最外层的value的值,所以当我们get(k)时,其实就是将value中的泛型取了出来。而泛型是Map类型,所以当我们再一次遍历其中的key,就能够得出key和value的值
- 所以再将里边的遍历之后,我们就可以得到想要的值了。
3.List嵌套List
-
有了上面两种的解释,写这一种其实也很简单了。所以我们直接写,一些地方就不做解释了
List<List<Person>> lists = new ArrayList<>(); List<Person> list1 =new ArrayList<>(); List<Person> list2 =new ArrayList<>(); Person person1 = new Person(); Person person2 = new Person(); Person person3 = new Person(); Person person4 = new Person(); person1.setName("sa"); person2.setName("sb"); person3.setName("sc"); person4.setName("sd"); person4.setUnit("4"); person1.setUnit("1"); person2.setUnit("2"); person3.setUnit("3"); list1.add(person1); list1.add(person2); list2.add(person3); list2.add(person4); lists.add(list1); lists.add(list2);
-
上面是赋值过程,就不再累述。下面进行取值过程,前面我们用了forEach和强化for,所以对于list嵌套list,我们选择另外一种也就是普通for循环来做
for (int i = 0; i<lists.size(); i++){ for(int j = 0; j<lists.get(i).size();j++){ System.out.println("姓名是"+lists.get(i).get(j).getName()+"名次是"+lists.get(i).get(j).getUnit()); } }
-
由于我们只需要用list.size就能知道集合的集合的长度,所以我们直接就可以让i和j都小于集合长度就能遍历了。