当前位置:   article > 正文

JAVA中 map list Stream流_java map里面存放list

java map里面存放list

MAP

java为数据结构中的映射定义了一个接口java.util.Map,他实现了四个类,分别是:HashMap,HashTable,LinkedHashMap,TreeMap 。Map 提供了一个更通用的元素存储方法。Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。Map不允许键重复,但允许值重复

1.HashMap:

最常用的Map,根据键的hashcode值来存储数据,根据键可以直接获得他的值(因为相同的键hashcode值相同,在地址为hashcode值的地方存储的就是值,所以根据键可以直接获得值),具有很快的访问速度,遍历时,取得数据的顺序完全是随机的,HashMap最多只允许一条记录的键为null,允许多条记录的值为null,HashMap不支持线程同步,即任意时刻可以有多个线程同时写HashMap,这样对导致数据不一致,如果需要同步,可以使用synchronziedMap的方法使得HashMap具有同步的能力或者使用concurrentHashMap。HashMap是输出数据时无序的,即不会记录插入的顺序。

2.HashTable:

与HashMap类似,不同的是,它不允许记录的键或值为空,支持线程同步,即任意时刻只能有一个线程写HashTable,因此也导致HashTable在写入时比较慢!

3.LinkedHashMap:

HashMap的一个子类,但它保持了记录的插入顺序,遍历时先得到的肯定是先插入的,也可以在构造时带参数,按照应用次数排序,在遍历时会比HahsMap慢,不过有个例外,当HashMap的容量很大,实际数据少时,遍历起来会比LinkedHashMap慢(因为它是链啊),因为HashMap的遍历速度和它容量有关,LinkedHashMap遍历速度只与数据多少有关

4.TreeMap:

实现了sortMap接口,能够把保存的记录按照键排序(默认升序)如果需要降序使用java.util包中DescendingMap(),也可以指定排序比较器,遍历时得到的数据是排过序的

5.MultiValueMap

   即一个键对应多个值,Spring的内部实现是LinkedMultiValueMap。

6.IdentityHashMap

   有一种key值可以重复的map.IdentityHashMap在比较键(和值)时使用引用相等性(==)而不是Map的equals()方法。IdentityHashMap使用引用相等性,因此两个键分别存储在内存中,因此它们的引用是不相等的。

  1. //内存中有两个相似但不同的实例
  2. Integer key1 = new Integer(10);
  3. Integer key2 = new Integer(10);
  4. //IdentityHashMap中的相同key
  5. IdentityHashMap<Integer, String> identityHashMap = new IdentityHashMap<>();
  6. identityHashMap.put(key1, "India");
  7. identityHashMap.put(key2, "USA");
  8. //Identity HashMap : {10=USA, 10=India}
  9. System.out.println("Identity HashMap : " + identityHashMap);

 keySet排序

  • Hashtable.keySet() 降序
  • TreeMap.keySet() 升序
  • HashMap.keySet() 乱序
  • LinkedHashMap.keySet() 原序
  1. TreeMap<String,String> map = new TreeMap<String, String>();
  2. map.put("name", "zychen");
  3. map.put("password", "123456");
  4. map.put("project", "base");
  5. map.put("tenantId", "192319387131");
  6. map.descendingMap();
  7. //根据指定的key获取对应的value
  8. Object name = map.get("name");
  9. if (name instanceof String) { //判断键值是否为String类型
  10. String value = (String) name; //获取指定的value
  11. }
  12. //通过key遍历
  13. for (String key: map.keySet()) {
  14. System.out.println("value:" + map.get(key));
  15. }
  16. MultiValueMap<String, String> valueMap = new LinkedMultiValueMap<>();
  17. valueMap.add("1", "1");
  18. valueMap.add("1", "2");
  19. valueMap.add("1", "3");
  20. valueMap.add("1", "4");
  21. valueMap.add("1", "5");
  22. valueMap.add("2", "1");
  23. valueMap.add("2", "2");
  24. valueMap.add("3", "1");
  25. for (Map.Entry<String, List<String>> stringListEntry : valueMap.entrySet()) {
  26. System.out.println("key:" + stringListEntry.getKey());
  27. List<String> value = stringListEntry.getValue();
  28. System.out.println("value:" + value);
  29. }

什么情况用什么类型的Map:

  • 在Map中插入,删除,定位元素:HashMap
  • 要按照自定义顺序或自然顺序遍历:TreeMap
  • 要求输入顺序和输出顺序相同:LinkedHashMap

Map遍历

  1. public static void main(String[] args) {
  2. //创建map集合对象
  3. Map<String, Integer> map = new HashMap<>();
  4. map.put("诸葛亮", 1);
  5. map.put("刘伯温", 2);
  6. map.put("张良", 3);
  7. map.put("东方朔", 4);
  8. map.put("东方朔", 5); //5 key值相同会被覆盖的特性
  9. map.containsKey("东方朔");
  10. //JDK8以下推荐写法
  11. for (Map.Entry<String, Integer> entry : map.entrySet()) {
  12. System.out.println(entry.getKey());
  13. System.out.println(entry.getValue());
  14. }
  15. //JDK8推荐写法,简捷
  16. map.forEach((key, value) -> {
  17. System.out.println(key);
  18. System.out.println(value);
  19. });
  20. }

List

  • Vector:线程安全的。
  • ArrayList:适合查找与顺序添加。但增删较慢。线程不同步
  • LinkedList:适合随机插入与删除。查询较慢

List转String[]

  1. List<String> list = new ArrayList<>();
  2. list.add("mm");
  3. list.add("nn");
  4. list.add("hh");
  5. String[] strings = list.toArray(new String[list.size()]);

List转String

  1. LinkedList<String> lList = new LinkedList<String>();
  2. lList.add("1");
  3. lList.add("2");
  4. lList.add("3");
  5. lList.add("4");
  6. lList.add("5");
  7. System.out.println(lList);
  8. lList.addFirst("0");
  9. System.out.println(lList);
  10. lList.addLast("6");
  11. System.out.println(lList);
  12. boolean res = llist.contains(4);
  13. if (res == true) {
  14. System.out.println("包含");
  15. }
  16. ArrayList<String> list = new ArrayList<String>() ;
  17. list.add("Tom");
  18. System.out.println(list.contains("Tom"));
  19. String allIndex = StringUtils.join(list,",");
  20. Set<String> set = new HashSet<>();
  21. set.add("hello1");
  22. set.add("hello2");
  23. set.add("hello3");
  24. Object[] arr = set.toArray();
  25. System.out.println(StringUtils.join(arr, ","));
  26. //复制,2个内存空间
  27. List<String> copy = new ArrayList<>(list);
  28. List<ApiVO> result = new LinkedList<>();
  29. List<Packages> agPkList = agMapper.getList(ordersNo);
  30. for (Packages info : agPkList) {
  31. ApiVO vo = new ApiVO();
  32. BeanUtils.copyProperties(info, vo);
  33. result.add(vo);
  34. }
  1. for (Map.Entry<String, List<People>> entry : collects.entrySet()) {
  2. for (People people : entry.getValue()) {
  3. if (people.getOfflineUnfreeze().equals("1")) {
  4. System.out.println("对象:" + people.getPhone());
  5. }
  6. }
  7. }
  8. public void splitDemo4(){
  9. String str= "aaa,bbb#ccc";
  10. //使用,和#分割字符串
  11. String[] split = str.split(",|#");
  12. for (int i = 0; i < split.length; i++) {
  13. System.out.println(split[i]);
  14. }
  15. }

List 分割

在工作中经常遇到需要将数组分割成多个子数组,然后进行批量处理的需求。那有没有比较优雅的实现呢 

引入依赖

  1. <dependency>
  2. <groupId>org.apache.commons</groupId>
  3. <artifactId>commons-collections4</artifactId>
  4. <version>4.4</version>
  5. </dependency>

代码演示

  1. public static void main(String[] args) {
  2. //初始化数组
  3. List<Integer> parList = new ArrayList<>();
  4. IntStream.range(0, 30).forEach(parList::add);
  5. //分割成子数组
  6. List<List<Integer>> subList = ListUtils.partition(parList, 10);
  7. //遍历子数组
  8. subList.forEach(list -> {
  9. System.out.println(String.format("subList size:%s", list.size()));
  10. System.out.println(String.format("list:%s", list.toString()));
  11. });
  12. }

Stream

Map转换为List

  1. List<String> list = Lists.newArrayList("a", "b", "c", "a", "e", "f");
  2. String result = list.stream().collect(Collectors.joining()); //输出为 abcdef
  3. String result = list.stream().collect(Collectors.joining(",")); //输出为 a,b,c,d,e,f
  4. List<String> valueList = linkedMap.values().stream().collect(Collectors.toList());

过滤筛选

  1. List<Product> math = prodList.stream().filter(
  2. product -> product.getCategory().contains("啤酒") && "百威啤酒".equals(product.getName()))
  3. .collect(Collectors.toList());

提取 List 中的某个字段

List<Integer> ids = list.stream().map(User::getId).collect(Collectors.toList());

根据单一字段分组

  1. Product prod1 = new Product(1L, 1, new BigDecimal("15.5"), "面包", "零食");
  2. Product prod2 = new Product(2L, 2, new BigDecimal("20"), "饼干", "零食");
  3. Product prod3 = new Product(3L, 3, new BigDecimal("30"), "月饼", "零食");
  4. Product prod4 = new Product(4L, 3, new BigDecimal("10"), "青岛啤酒", "啤酒");
  5. Product prod5 = new Product(5L, 10, new BigDecimal("15"), "百威啤酒", "啤酒");
  6. Product prod6 = new Product(5L, 7, new BigDecimal("25"), "百威啤酒", "啤酒");
  7. List<Product> prodList = List.of(prod1, prod2, prod3, prod4, prod5, prod6);
  8. Map<String, List<Product>> map1 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory));

输出结果:

  1. 啤酒=[Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}, Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}, Product{id=5, num=7, price=25, name='百威啤酒', category='啤酒'}]
  2. 零食=[Product{id=1, num=1, price=15.5, name='面包', category='零食'}, Product{id=2, num=2, price=20, name='饼干', category='零食'}, Product{id=3, num=3, price=30, name='月饼', category='零食'}]

根据不同条件分组

  1. Map<String, List<Product>> map3 = prodList.stream().collect(Collectors.groupingBy(item -> {
  2. if (item.getNum() > 3) {
  3. return "num大于3";
  4. } else if (item.getNum() < 3) {
  5. return "num小于3";
  6. } else {
  7. return "num等于3";
  8. }
  9. }));
  10. Set<Map.Entry<String, List<Product>>> entries3 = map3.entrySet();
  11. for (Map.Entry<String, List<Product>> entry : entries3) {
  12. System.out.println(entry);
  13. }

输出结果

  1. num小于3=[Product{id=1, num=1, price=15.5, name='面包', category='零食'}, Product{id=2, num=2, price=20, name='饼干', category='零食'}]
  2. num等于3=[Product{id=3, num=3, price=30, name='月饼', category='零食'}, Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒'}]
  3. num大于3=[Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒'}, Product{id=5, num=7, price=25, name='百威啤酒', category='啤酒'}]

使用分组减少循环层数

  1. for (AccountRelationVo relationVo : relationList) {
  2. for (GatewayRoutingPageVo gatewayRoutingVo : gatewayRoutingList) {
  3. if (relationVo.getGatewayName().equals(gatewayRoutingVo.getName())) {
  4. BeanUtils.copyProperties(gatewayRoutingVo, relationVo);
  5. break;
  6. }
  7. }
  8. }
  9. //使用分组后
  10. for (AccountRelationVo relationVo : relationList) {
  11. BeanUtils.copyProperties(gatewayRoutingMapList.get(relationVo.getGatewayName()), relationVo);
  12. }

去重

list = list.stream().distinct().collect(Collectors.toList());

toMap

toMap(Function, Function) 返回一个 Collector,它将元素累积到一个 Map中,其键和值是将提供的映射函数应用于输入元素的结果。

  1. // 获取正确的<id, phoneNum> map 报空指针,解决方案
  2. Map<Integer, String> stringMap = new HashMap();
  3. if (Phones.size() > 0) {
  4. stringMap = Phones.stream().collect(Collectors.toMap(Phones::getId,e -> e.getPhoneNum() == null ? "" : e.getPhoneNum()));
  5. }
  6. /**
  7. * id作为Map的key,name作为value的集合
  8. */
  9. Map<Integer, String> collect1 = employeeList.stream().collect(Collectors.toMap(Employee::getId, Employee::getName));
  10. System.out.println(collect1);//{101=张三, 102=李四, 103=王五, 104=赵六}

forEach

对于java8中的特殊写法lamada表达式中,不能使用break,会提示错误;java8中使用return,会跳出当前循环,继续下一次循环,作用类似continue;

foreach循环可以遍历输出数组里面的元素,但是不能通过foreach来修改元素.

做forEach,需要把外面的变量赋值如int,long,boolean,需要外面定义原子类型AtomicReference

  1. //循环遍历赋值
  2. list.forEach(f -> f.setCallId("'" + f.getCallId()));
  3. list.forEach(objTrunk -> {
  4. user.setAreaCode(objTrunk.getAreaCode());
  5. });
  6. AtomicReference<Boolean> isAiExecSuccess = new AtomicReference<>(false);
  7. operationRecords.forEach(rec -> {
  8. if (StringUtils.isNotEmpty(rec.getRemark())) {
  9. if (rec.getRemark().equals("数据执行成功")) {
  10. isAiExecSuccess.set(true);
  11. return;
  12. }
  13. }
  14. });

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/289136
推荐阅读
相关标签
  

闽ICP备14008679号