当前位置 博文首页 > 文章内容

    Java8、9中的Collection API的增强功能

    作者: 栏目:未分类 时间:2020-08-31 18:01:13

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    1.集合工厂

      使用java创建由少量元素构成的列表

            ArrayList<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
    

      不过这种方法比较low,而且代码很多。

      更加简洁的方式是  Arrays.asList()的方法,不过通过此方法,创建的是一个固定大小的列表,列表的元素可以更新,但是不能增加或者删除,否则会报错。

     

    那Set集合也有对应的工厂方法吗?我们并没有发现有这种Arrays.asSet()类似的方法,不过我们可以通过Set的构造方法创建。

    Set<String> set = new HashSet<>(Arrays.asList("a","b"));
    

     不过通过此方法创建的是可变的Set。

    Map呢,目前没有发现可以优雅创建小规模的map,不过java9新引入的工厂方法,可以小规模创建List,set,Map。

    1.1 List工厂

    List.of()方法

    我们发现List接口中有多个of()的重载方法

     

    并且创建的是一个只读的list,不能新增,修改和删除,否则报错。

     

     

     

     

    1.2 Set工厂

    同理,set中也存在of()方法,并且创建的是不可变的Set集合 。并且如果of的参数列表中存在相同元素会报错。

     

     

    1.3 Map工厂

    与创建List和Set相比,创建Map稍微复杂一点。

    工厂方法:Map.of(),该方法交替地以列表中地元素作为键和值。

     

     

     Map.ofEntries()方法,接收以变长参数列表形式组织地Map.Entry<k,v>对象作为参数。

     

     

    2.使用List和Set

    2.1 removeIf方法

    有时候我们需要按照指定条件移除List中的元素,如下代码:

        @Test
        public void test(){
            List<User> users = new ArrayList<>();
            users.add(new User("a",20));
            users.add(new User("b",18));
            users.add(new User("b",17));
            for(User user : users){
                if(user.getAge()>=18){
                    users.remove(user);
                }
            }
            System.out.println(users);
        }
    

    但是,很遗憾,会报异常,是因为增强for循环底层使用的是iterator迭代器,通过List.remove()方法操作集合后,迭代器对象的状态没有与集合对象的状态同步,我们需要改成iterator.remove()去修改集合。

    但是java8以后,通过removeIf方法,就可以避免上述缺陷。

    users.removeIf(u->u.getAge()>=18);
    

    2.2 replaceAll方法

    List接口中提供的replaceAll方法让我们可以使用一个新的元素去替换列表中满足要求的每个元素。  

        @Test
        public void test2(){
            List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
            list.replaceAll(a-> a>3 ? a+1 : a-1);
            System.out.println(list);
        }
    

    3.使用Map 

    3.1 forEach方法

    一直以来,遍历Map一直都很麻烦,使用Map.Entry<K,V>迭代器遍历或者使用map.keySet对键进行遍历。

    从java8开始,Map接口中提供了forEach的默认方法,该方法接收一个BiConsumer,以键和值作为参数。

        @Test
        public void test3(){
            Map<Integer ,User> userMap = new HashMap<>();
            userMap.put(1,new User("a",20));
            userMap.forEach((k,v)-> System.out.println(k+":"+v));
        }
    

    3.2 排序

     有两种新的工具可以对Map的键或值排序

    Entry.comparingByValue 和 Entry.comparingByKey

        @Test
        public void test4(){
            Map<Integer ,User> userMap = new HashMap<>();
            userMap.put(1,new User("a",20));
            userMap.put(2,new User("a",18));
            userMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.comparing(User::getAge))).forEach(System.out::println);
        }
            Map<Integer ,User> userMap = new HashMap<>();
            userMap.put(1,new User("a",20));
            userMap.put(2,new User("b",18));
            userMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(System.out::println);
    

    3.3 getOrDefualt()方法

    如果我们查找的键在Map中不存在时,会收到一个null,在程序中可能会造成空指针异常。

    使用getOrDefault方法,接收第一个参数作为键,第二个参数作为默认值。当键在map中找不到时,会将这个默认值返回。

            Map<Integer ,User> userMap = new HashMap<>();
            userMap.put(1,new User("a",20));
            userMap.put(2,new User("b",18));
            User user = userMap.getOrDefault(3,new User("c",22));
            System.out.println(user);
    

    3.4 计算模式

    有时,我们希望依据键在Map中存在或者缺失的情况,有条件地执行某个操作,并存储计算的结果

    computeIfAbset:如果指定的键没有对应的值(没有改键或者键对应的值为空),那么使用该键计算新的值,并添加到Map中。

    computeIfPresent:如果指定的键在Map中存在,就计算该键的新值,并添加到Map中。

    compute:使用指定的键计算新的值,并添加到Map中。