美文网首页
Guava的实践之集合

Guava的实践之集合

作者: 梦想实现家_Z | 来源:发表于2019-03-24 16:20 被阅读0次

    相较于Guava的基础工具类,集合类是最成熟和为人所知的了。
    1.不可变集合
    不可变集合,顾名思义就是不可以被改变的集合。该集合一旦被创建,在它的整个生命周期内都是不可以被改变的。
    根据不可变集合的特性,它可以很自然地用作常量,它能保证在多线程环境中的安全,也是一个很好的防御性编程的技术实践。

    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableSet;
    import com.google.common.collect.ImmutableSortedSet;
    import com.google.common.collect.Lists;
    
    import java.util.List;
    
    public class GuavaMain {
    
        /**
         * 不可变集合
         */
        private static void immutableTest() {
            List<String> list = Lists.newArrayList();
            list.add("a");
            list.add("b");
            list.add("c");
            //使用copyOf()创建不可变集合
            ImmutableList imList = ImmutableList.copyOf(list);
            System.out.println("imList:" + imList);
    
            //即使对原始集合做了修改,也不影响不可变集合的数据
            list.add("e");
            System.out.println("imList:" + imList);
    
            //使用of()创建可排序不可变集合
            ImmutableSortedSet<String> sortSet = ImmutableSortedSet.of("k", "Z", "y", "w");
            System.out.println("sortSet:" + sortSet);
    
            //使用builder()创建
            ImmutableSet<String> imSet = ImmutableSet.<String>builder()
                    .add("hello")
                    .add("world")
                    .build();
            System.out.println("imSet:" + imSet);
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            immutableTest();
        }
    }
    

    以上是三种创建不可变集合的方式。其他的读操作API和JDK集合类相似,写操作API被禁用。小伙伴可以自己去尝试使用读操作API。
    剩下的还有很多不可变集合:

    可变集合类型            JDK or Guava        Guava不可变集合
    
    Collection                JDK        ImmutableCollection
    List                      JDK        ImmutableList
    Set                       JDK        ImmutableSet
    SortedSet/NavigableSet    JDK        ImmutableSortedSet
    Map                       JDK        ImmutableMap
    SortedMap                 JDK        ImmutableSortedMap
    Multiset                 Guava       ImmutableMultiset
    SortedMultiset           Guava       ImmutableSortedMultiset
    Multimap                 Guava       ImmutableMultimap
    ListMultimap             Guava       ImmutableListMultimap
    SetMultimap              Guava       ImmutableSetMultimap
    BiMap                    Guava       ImmutableBiMap
    ClassToInstanceMap       Guava       ImmutableClassToInstanceMap
    Table                    Guava       ImmutableTable
    

    2.新的集合类型

    Multiset
    JDK提供了List和Set两类集合,List的元素特点是有序可重复,Set的元素是无序不可重复,Multiset正好处于两者的灰色地带,它的元素特点是无序可重复。

    import com.google.common.collect.*;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class GuavaMain{
    
        /**
         * multiset测试
         */
        private static void multisetTest() {
            List<String> list = new ArrayList<>();
            list.add("hello");
            list.add("world");
            list.add("java");
            list.add("python");
            Multiset<String> multiset = HashMultiset.create();
            multiset.add("hello");
            multiset.add("go");
            multiset.add("javascript");
            multiset.add("css");
            multiset.add("html");
            multiset.addAll(list);
            //打印
            System.out.println(multiset);
    
            //计算hello的次数
            int num = multiset.count("hello");
            System.out.println("num:" + num);
            //设置"java"的数量
            multiset.setCount("java", 2);
            System.out.println(multiset);
            //统计不重复元素的数量
            int elementSize = multiset.elementSet().size();
            System.out.println("elementSize:" + elementSize);
            //删除hello
            multiset.remove("hello", num);
            System.out.println(multiset);
            //添加5个kotlin
            multiset.add("kotlin", 5);
            System.out.println(multiset);
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            multisetTest();
        }
    }
    

    除了以上HashMultiset的实现,Guava还有很多其他Multiset的实现:

    HashMultiset
    TreeMultiset
    LinkedHashMultiset
    ConcurrentHashMultiset
    ImmutableMultiset
    

    Multimap
    先解释一下Multimap的结构,大多数小伙伴都用过Map<K,List<V>>或者Map<K,List<V>>,类似于:

    key : [value1, value2, value3...]
    

    下面直接上代码示例:

    import com.google.common.collect.*;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    public class GuavaMain {
    
        /**
         * multimap测试
         */
        private static void multimapTest() {
            ArrayListMultimap<String, Integer> listMultimap = ArrayListMultimap.create();
            listMultimap.put("a", 1);
            listMultimap.put("a", 1);
            listMultimap.put("a", 1);
            listMultimap.put("a", 1);
            listMultimap.put("b", 20);
            listMultimap.put("b", 2);
    
            //{a->[1,1,1,1],b->[20,2]}
            System.out.println(listMultimap);
    
            //创建HashMultimap
            HashMultimap setMultimap = HashMultimap.create(listMultimap);
            //{a->[1],b->[20,2]}
            System.out.println(setMultimap);
            //获取a对应的value,以便对其进行操作
            Set<Integer> set = setMultimap.get("a");
            System.out.println(set);
            //删除所有的value
            set.clear();
            //{b=[20, 2]}
            System.out.println(setMultimap);
    
            //类型转换
            Map<String, Set<Integer>> map = setMultimap.asMap();
            //{b=[20, 2]}
            System.out.println(map);
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            multimapTest();
        }
    }
    

    以上是Multimap的一个简单实践,Guava还提供了其他多种形式的Multimap:

    ArrayListMultimap
    HashMultimap
    LinkedListMultimap
    LinkedHashMultimap
    TreeMultimap
    ImmutableListMultimap
    ImmutableSetMultimap
    

    BiMap
    BiMap实现的功能就是可以将键值反转,相互映射。假如key:value一一对应,value不重复,想要通过value映射key,需要同时维护两个Map,BiMap的出现就解决了这个问题。

    import com.google.common.collect.*;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    public class GuavaMain{
    
        /**
         * BiMap测试
         */
        private static void biMapTest() {
            BiMap<String, Integer> userMap = HashBiMap.create();
    
            userMap.put("Zz", 1);
            userMap.put("Kelly", 2);
            userMap.put("James", 3);
            userMap.put("Bob", 4);
            //{Zz=1, Kelly=2, James=3, Bob=4}
            System.out.println(userMap);
    
            String name = userMap.inverse().get(1);
            //Zz
            System.out.println(name);
            userMap.forcePut("Zz", 2);
            //{Zz=2, James=3, Bob=4}
            System.out.println(userMap);
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            biMapTest();
        }
    }
    

    Table
    当你需要使用两个键做索引的时候,就需要使用到Table的功能了。

    import com.google.common.collect.*;
    import lombok.Data;
    import lombok.ToString;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    public class GuavaMain {
    
        @Data
        @ToString
        private static class Point {
            private final Integer x;
            private final Integer y;
    
            public Point(final Integer x, final Integer y) {
                this.x = x;
                this.y = y;
            }
        }
       /**
         * table测试
         */
        private static void tableTest() {
            Table<Integer, Integer, Point> table = HashBasedTable.create();
            table.put(10, 5, new Point(10, 5));
            table.put(3, 29, new Point(3, 29));
            table.put(10, 15, new Point(10, 15));
            table.put(3, 5, new Point(3, 5));
    
            /**
             * {
             *  10={5=GuavaMain.Point(x=10, y=5),
             *  15=GuavaMain.Point(x=10, y=15)},
             *   3={29=GuavaMain.Point(x=3, y=29),
             *   5=GuavaMain.Point(x=3, y=5)}
             *   }
             */
            System.out.println(table);
    
            Map<Integer, Point> row = table.row(10);
            /**
             * {
             *  5=GuavaMain.Point(x=10, y=5),
             * 15=GuavaMain.Point(x=10, y=15)
             * }
             */
            System.out.println(row);
    
    
            Map<Integer, Point> column = table.column(5);
            /**
             * {
             * 10=GuavaMain.Point(x=10, y=5),
             *  3=GuavaMain.Point(x=3, y=5)
             * }
             */
            System.out.println(column);
    
            Set<Table.Cell<Integer, Integer, Point>> cells = table.cellSet();
            /**
             * [
             * (10,5)=GuavaMain.Point(x=10, y=5),
             * (10,15)=GuavaMain.Point(x=10, y=15),
             * (3,29)=GuavaMain.Point(x=3, y=29),
             * (3,5)=GuavaMain.Point(x=3, y=5)
             * ]
             */
            System.out.println(cells);
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            tableTest();
        }
    }
    

    同样的,Guava也同样提供来多种实现:

    HashBasedTable
    TreeBasedTable
    ImmutableBasedTable
    ArrayTable
    

    3.强大的集合工具类
    和Cllections一样,Guava同样提供来强大的工具类来更方便地操纵集合。
    Iterables

    import com.google.common.collect.*;
    import com.google.common.primitives.Ints;
    import lombok.Data;
    import lombok.ToString;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    public class GuavaMain {
       /**
         * Iterables测试
         */
        private static void iterablesTest() {
            Iterable<Integer> iterable = Iterables.concat(Ints.asList(1, 2, 3), Ints.asList(4, 5, 6));
            //[1, 2, 3, 4, 5, 6]
            System.out.println(iterable);
    
            int n = Iterables.frequency(iterable, 1);
            //返回1在iterable中的频率
            System.out.println(n);
    
            //将iterable按指定大小分割
            Iterable<List<Integer>> iterable1 = Iterables.partition(iterable, 2);
            //[[1, 2], [3, 4], [5, 6]]
            System.out.println(iterable1);
    
            //判断两个Iterable是否equal,元素和顺序都要一致的前提下,返回true;否则返回false
            Iterables.elementsEqual(iterable, iterable1);
    
            //获取第一个元素
            Integer first = Iterables.getFirst(iterable, -1);
            System.out.println(first);
    
            //获取指定索引的元素
            Integer subElement = Iterables.get(iterable, 3);
            System.out.println(subElement);
        }
    
        /**
         * 主函数
         *
         * @param args
         */
        public static void main(String[] args) {
            iterablesTest();
        }
    }
    

    Lists

    private static void listsTest() {
            List<Integer> list1 = Lists.newArrayList();
            for (Integer i = 0; i < 10; i++) {
                list1.add(i);
            }
            //按指定大小分割list
            List<List<Integer>> partitionList = Lists.partition(list1, 5);
            //[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
            System.out.println(partitionList);
    
            //反转list
            List<Integer> reverseList = Lists.reverse(list1);
            //[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
            System.out.println(reverseList);
        }
    

    Sets

    private static void setsTest() {
            Set<Integer> set1 = Sets.newHashSet();
    
            Set<Integer> set2 = Sets.newHashSet(5, 6, 7, 8, 9);
            for (Integer i = 0; i < 5; i++) {
                set1.add(i);
            }
            //合并Set元素
            Sets.SetView<Integer> unionSetView = Sets.union(set1, set2);
            //[0, 1, 2, 3, 4, 8, 9, 5, 6, 7]
            System.out.println(unionSetView);
    
            //交集
            Sets.SetView<Integer> intersectionSetView = Sets.intersection(set1, unionSetView);
            //[0, 1, 2, 3, 4]
            System.out.println(intersectionSetView);
    
        }
    

    上面只是简单地使用了几个工具类,Guava还提供了Maps,Multisets,Multimaps等等强大的集合工具类,感兴趣的小伙伴可以去尝试使用一下,真的特别好用。
    以上是我对于Guava中集合的一些简单使用,主要目的还是让不了解Guava的小伙伴有一个入门。

    相关文章

      网友评论

          本文标题:Guava的实践之集合

          本文链接:https://www.haomeiwen.com/subject/rruevqtx.html