zoukankan      html  css  js  c++  java
  • 七、Guava 工具集

    Google Guava 工具集简介

    Guava工程包含了若干被Google的Java项目广泛依赖的核心库,例如:集合、缓存、原生类型支持、并发库、通用注解、字符串处理、I/O等等。
    所有这些工具每天都在被Google的工程师应用在产品服务中。

    使用和避免null

    大多数情况下,使用null表明的是某种缺失情况。
    Guava引入Optionl表明可能null的T类型引用。Optional实例可能包含非null的引用(引用存在),也可能什么也不包括(引用缺失)。正是受到Guava的启发,Java8将Optional类做为一个新特性引入进Java8的类库。

    实例

    /**
     * @author fangliu
     * @date 2020-02-15
     * @description 学习Java8中的optional使用方法
     */
    public class OptionalTest {
        @Test
        public  void test() throws Throwable {
            /**
             * 三种创建Optional
             */
            // 创建空的Optional对象
            Optional.empty();
            // 使用非null值创建Optional对象
            Optional.of("Optional");
            // 使用任意值创建Optional对象
            Optional optional = Optional.ofNullable(null);
            /**
             * 判断是否引用缺失的方法(建议不直接使用)
             */
            optional.isPresent();
            /**
             * optional引用存在时执行
             * 类似的方法:map filter flatMap
             */
            optional.ifPresent(System.out::println);
    
            /**
             * 当optional引用缺失时执行
             * orElse():如果有值则将其返回,否则返回指定的其它值。
             * orElseGet():如果有值则将其返回,否则调用函数并将其返回调用结果。
             * 由于orElseGet()不是每次都会调用传入的方法,所以orElseGet()方法在性能上要优于orElse()方法。
             */
            optional.orElse(get("引用缺失"));
            optional.orElseGet(()->{
                // 自定义引用缺失时的返回值
                System.out.println("自定义引用缺失");
                return "自定义引用缺失";
            });
    
            optional.orElseThrow(()->{
                throw  new RuntimeException("引用缺失异常");
            });
        }
        public static int get(String name) {
            System.out.println(name);
            return 1;
        }
    }
    

    不可变对象的优点

    • 当对象被不可信的库调用时,不可变形式是安全的
    • 不可变对象被多个线程调用时,不存在竞态条件问题
    • 不可变集合不需要考虑变化,因此可以节省时间和空间
    • 不可变对象因为有固定不变,可以作为常量来安全使用

    JDK提供的unmodifiableXXX方法

    • 笨重而且累赘
    • 不安全
    • 低效

    实例

    /**
     * @author fangliu
     * @date 2020-02-16
     * @description 不可变集合用法
     */
    public class ImmutableTest {
        public static void test(List<Integer> list){
            list.remove(0);
        }
        @Test
        public  void test(){
            List<Integer> list= new ArrayList<Integer>();
            list.add(1);
            list.add(2);
            list.add(3);
            // 通过Collections的unmodifiableList方法让list不可变
            List<Integer> newList = Collections.unmodifiableList(list);
            test(newList);
            System.out.println(list);
        }
    }
    

    Guava提供的不可变集合的三种创建方式

    • copyOf方法:ImmutableSet.copyOf(set)
    • of方法:ImmutableSet.of("a","b","c")
    • Builder工具:ImmutableSet.builder().build()
    
        public void immutable(){
            List<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(2);
            list.add(3);
    
            /**
             * 构造不可变集合对象三种方式
             */
            // 通过已经存在的集合创建
            ImmutableSet.copyOf(list);
            // 通过初始值,直接创建不可变集合
            ImmutableSet immutableSet = ImmutableSet.of(1,2,3,4,5);
            //以builder方式创建
            ImmutableSet.builder()
                    .add(1)
                    .addAll(Sets.newHashSet(2,3,4))
                    .add(5)
                    .build();
    
        }
    

    新集合类型

    Guava引入了很多JDK没有的,但明显有用的新集合类型。这些类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念

    Set 无序不可重复集合
    List 有序可重复集合
    Multiset 无序可重复集合

    实例

    /**
     * @author fangliu
     * @date 2020-02-16
     * @description 使用Multiset统计一首古诗的文字出现频率
     */
    public class MultisetTest {
        private static final String text =
                "择一城终老,遇一人白首。挽一帘幽梦,许一世倾城。写一字决别,言一梦长眠。我倾尽一生,囚你无期。 " +
                "择一人深爱,等一人终老。痴一人情深,留一世繁华。断一根琴弦,歌一曲离别。我背弃一切,共度朝夕。";
        private static final String text1 =
                "三生有幸遇见你 纵使悲凉也是情;" +
                "一世无缘却相逢,即便欣喜也无果!";
        @Test
        public void handle (){
            // multiset创建
            Multiset<Character> multiset = HashMultiset.create();
            // string 转化成char数组
            char[] chars = text.toCharArray();
            // 遍历数组,添加到multiset中
            Chars.asList(chars)
                    .stream()
                    .forEach(charItem->multiset.add(charItem));
            System.out.println("size:"+multiset.size());
            System.out.println("count:"+multiset.count('人'));
        }
    
    }
    

    集合工具类

    Guava为集合类提供了许多工具方法。这也是Guava最流行和成熟的部分之一
    常见的集合工具类如:Lists,Sets,Maps等。

    实例

    /**
     * @author fangliu
     * @date 2020-02-16
     * @description Guava集合使用
     */
    public class CollectionsTest {
        /**
         * Sets工具类的常用方法
         * 并集/交集/差集/分解集合中的所有子集/求两个集合的笛卡尔积
         * <p>
         * Lists工具类的常用方式
         * 反转/拆分
         */
        private static final Set set1 = Sets.newHashSet(1, 2, 3, 4);
    
        private static final Set set2 = Sets.newHashSet(4, 5, 6);
    
        // 并集
        @Test
        public void union() {
            Set<Integer> set = Sets.union(set1, set2);
            System.out.println(set);
        }
    
        // 交集
        @Test
        public void intersection() {
            Set<Integer> set = Sets.intersection(set1, set2);
            System.out.println(set);
        }
    
        // 差集
        @Test
        public void difference() {
            // 属于set1并且不属于set2
            Set<Integer> set = Sets.difference(set1, set2);
            System.out.println(set);
            // 相对差集:set1、set2差集之外的值
            set = Sets.symmetricDifference(set1, set2);
            System.out.println(set);
        }
    
        // 分解集合中的所有子集
        @Test
        public void powerSet() {
            // 属于set1并且不属于set2
            Set<Set<Integer>> set = Sets.powerSet(set1);
            System.out.println(JSON.toJSONString(set));
        }
    
        // 求两个集合的笛卡尔积
        @Test
        public void cartesianProduct() {
            // 属于set1并且不属于set2
            Set<List<Integer>> set = Sets.cartesianProduct(set1, set2);
            System.out.println(JSON.toJSONString(set));
        }
    
        // 拆分
        @Test
        public void partition() {
            List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
            // 几个为一组拆分
            List<List<Integer>> partition = Lists.partition(list, 2);
            System.out.println(JSON.toJSONString(partition));
        }
    
        // 反转
        @Test
        public void reverse() {
            List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
            List<Integer> reverse = Lists.reverse(list);
            System.out.println(JSON.toJSONString(reverse));
        }
    }
    

    IO综述

    • ByteStreams:提供对InputStream/OutputStream的操作
    • CharStreams:提供对Reader/Writer的操作

    源(Source)与汇(Sink)的抽象

    • 源是可读的:ByteSource/CharSource
    • 汇是可写的:ByteSink/CharSink

    实例

    /**
     * @author fangliu
     * @date 2020-02-16
     * @description 源(Source)与汇(Sink)对文件进行常用操作
     */
    public class IOTest {
        @Test
        public void copyFile() throws IOException {
            /**
             * 创建对应的Source和Sink
             */
            CharSource charSource = Files.asCharSource(
                    new File("SourceText.txt"), Charsets.UTF_8);
            CharSink charSink = Files.asCharSink(
                    new File("TargetText.txt"),Charsets.UTF_8
            );
            /**
             * 拷贝
             */
            charSource.copyTo(charSink);
        }
    }
    
  • 相关阅读:
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    PHP中foreach用法详细讲解
  • 原文地址:https://www.cnblogs.com/bigfairy/p/14002086.html
Copyright © 2011-2022 走看看