zoukankan      html  css  js  c++  java
  • 强大的Guava中的新集合类型: Multiset, Multimap, BiMap, Table, ClassToInstanceMap, RangeSet, RangeMap等

    一 Multiset

    /**
         * 新类型集合: Multiset: Multiset就是可以保存多个相同的对象,并且无序
         *                      占据了List和Set之间的一个灰色地带
         *           其他实现: TreeMultiset LinkedHashMultiset
         *                  ConcurrentHashMultiset
         *                  ImmutableMultiset
         */
        @Test
        public void newList(){
            HashMultiset<Integer> multiset = HashMultiset.create();
            multiset.add(2,3);//添加指定个数的重复元素
            multiset.count(2); //获取元素在集合中的个数
            multiset.remove(2,2); //移除指定的个数元素
            multiset.setCount(5,2); //和add相同
            multiset.setCount(5,2,3); //修改集合中元素的个数,2个改为3个
            //常见功能,统计每个字符出现的此数
            String strWorld="wer|dffd|ddsa|dfd|dreg|de|dr|ce|ghrt|cf|gt|ser|tg|ghrt|cf|gt|" +
                    "ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr|wer|dffd|ddsa|dfd|dreg|de|dr|" +
                    "ce|ghrt|cf|gt|ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr";
            HashMultiset<String> multisetStr = HashMultiset.create();
            multisetStr.addAll(Arrays.asList(strWorld.split("\|")));
            multisetStr.elementSet().forEach(x->System.out.println(x+" :"+multisetStr.count(x)));
        }

    二 Multimap

        /**
         * Multimap 提供了一个方便地把一个键对应到多个值的数据结构
         *  ”键-单个值映射”的集合(例如:a -> 1 a -> 2 a ->4 b -> 3 c -> 5)
         *  用于替代 Map<K, List<V>>或Map<K, Set<V>>这种结构
         *  提供多种实现 ArrayListMultimap       HashMultimap  等
         */
        @Test
        public void multiMapTest(){
            Multimap<String, User> multimap = ArrayListMultimap.create();
            for (int i = 1; i <= 5; i++) {
                multimap.put("one",User.of().setAge(23).setName("用户"+i).setLevel(i));
            }
            for (int i = 1; i <= 5; i++) {
                multimap.put("two",User.of().setAge(20).setName("用户"+i).setLevel(i));
            }
            multimap.containsKey("one"); //判断是否包含有key
            multimap.size(); //所有元素个数
            //转换为map数据结构
            Map<String, Collection<User>> map = multimap.asMap();
            multimap.remove("key",User.of());//移除key对应下指定的value
            multimap.keys();//获取所有的key
            multimap.values(); //获取所有的value
            multimap.removeAll("one");//移除key对应的所有元素
            multimap.replaceValues("two", Lists.newArrayList(User.of()));// 替换key对应的元素
        }

    三 BiMap

        /**
         * BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构
         *     能非常方便的实现map<key,value>的转置要求,也就是value变为key,key变为value
         *    保证值是唯一的,因此返回Set而不是普通的Collection
         */
        @Test
        public void biMapTest(){
            BiMap<Integer, String> hashBiMap = HashBiMap.create();
            hashBiMap.put(1,"用户1");
            hashBiMap.put(2,"用户2");
            hashBiMap.put(3,"用户3");
            //键值转换
            BiMap<String, Integer> inverseBiMap = hashBiMap.inverse();
            inverseBiMap.entrySet().forEach(x->
                    System.out.println("key:"+x.getKey()+", value:"+x.getValue()));
            //因为值唯一(需要翻转时候key唯一),所以添加时如果value存在抛异常,可使用forcePut强制替换键
            // hashBiMap.put(4,"用户3");  IllegalArgumentException
            hashBiMap.forcePut(4,"用户3"); //强制替换用户3的键为4
            //根据kv进行消费返回结果
            String compute = hashBiMap.compute(4, (x, y) -> x + y);
            System.out.println(compute); // 4用户3
        }

    四 Table

        /**
         * Table是Guava提供的一个接口 Interface Table(R,C,V),
         * 由rowKey(行)+columnKey(列)+value组成 ,它有两个支持所有类型的键:”行”和”列”
         * 其实就是有了双键的Map
         *  例如: 学生(rowkey)--课程(columkey)--成绩(value)
         */
        @Test
        public void tableTest(){
            Table<String, String, Integer> hashBasedTable = HashBasedTable.create();
            hashBasedTable.put("一班","数学",97);
            hashBasedTable.put("二班","英语",85);
            hashBasedTable.put("二班","语文",70);
            hashBasedTable.get("一班", "数学"); //通过两个key获取value
            hashBasedTable.columnKeySet(); //获取列key  [数学, 英语, 语文]
            hashBasedTable.rowKeySet();//获取行key   [一班, 二班]
            //获取所有行的set
            hashBasedTable.cellSet().forEach(x->
                    System.out.println("rowKey:"+x.getRowKey()+
                            ", columnKey:"+x.getColumnKey()+", value:"+x.getValue()));
            hashBasedTable.row("二班"); //根据rowKey获取所有对应的columnKey和value的 map
            hashBasedTable.column("数学"); //根据columnKey获取所有对应的rowKey和value 的 map
            hashBasedTable.rowMap(); //获取rowKey对应的 列-value map
            hashBasedTable.remove("一班","数学"); //移除元素
            hashBasedTable.columnMap(); //获取columnKey对应的 rowKey-value map
    
        }

    五 ClassToInstanceMap

        /**
         *  ClassToInstanceMap是一种特殊的Map:它的键是类型,而值是符合键所指类型的对象
         */
        @Test
        public void classToInstanceMapTest(){
            //可存放所有数字类型的map
            ClassToInstanceMap<Number> numberDefaults= MutableClassToInstanceMap.create();
            numberDefaults.putInstance(Integer.class, 1);
            numberDefaults.putInstance(Double.class, 1.00);
            numberDefaults.putInstance(BigDecimal.class, new BigDecimal("52"));
            numberDefaults.put(Integer.class, 2);
            numberDefaults.replace(Integer.class, 3); //修改
            numberDefaults.getInstance(Integer.class); //获取value 3
            //通过传入新值和旧值计算,修改旧值,例: 将Integer,class的值+3
            numberDefaults.merge(Integer.class,2,(x,y)->x.intValue()+y.intValue());
            numberDefaults.forEach((x,y)-> System.out.println(x+","+y));
            /**
             * class java.lang.Double,1.0
             * class java.math.BigDecimal,52
             * class java.lang.Integer,5
             */
    
    
        }

    六 RangeSet

        /**
         * RangeSet描述了一组不相连的、非空的区间。
         * 当把一个区间添加到可变的RangeSet时,所有相连的区间会被合并,空区间会被忽略
         */
        @Test
        public void rangeSetTest(){
            RangeSet<Comparable<?>> treeRangeSet = TreeRangeSet.create();
            treeRangeSet.add(Range.closed(1,10));
            //连续区间会被合并   [15,22]
            treeRangeSet.add(Range.closedOpen(15,20));
            treeRangeSet.add(Range.closed(18,22));
            treeRangeSet.remove(Range.closed(2,8)); //移除.,会把区间分割
            //遍历所有区间
            treeRangeSet.asRanges().forEach(x-> System.out.println(x));
    
            // 返回一个目前所有区间里的最小值到最大值的区间
            treeRangeSet.span();// [1..22]
            //获取互补区间
            treeRangeSet.complement();//[(-∞..1), (10..15), (22..+∞)]
            treeRangeSet.contains(14); //是否包含此元素  false
            //返回元素所在的区间,不包含返回null
            treeRangeSet.rangeContaining(14);
            // 是否包含某个区间
            treeRangeSet.encloses(Range.closed(1, 10)); //true
            //返回交集
            treeRangeSet.subRangeSet(Range.closed(1, 4));
        }

    七 RangeMap

        /**
         * RangeMap描述了”不相交的、非空的区间”到特定值的映射。即 key是区间, value是值的map
         * 和RangeSet不同,RangeMap不会合并相邻的映射,即便相邻的区间映射到相同的值
         */
        @Test
        public void rangeMap(){
            RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
            rangeMap.put(Range.closed(1, 10), "foo");
            rangeMap.put(Range.open(3, 6), "bar");
            rangeMap.put(Range.open(10, 20), "foo");
            rangeMap.remove(Range.closed(5, 11));
            //根据区间里的任意值获取value
            rangeMap.get(1); //foo
            //获取map视图进行迭代
            rangeMap.asMapOfRanges().forEach((x,y)-> {
                System.out.println(x);  // [1..3]
                System.out.println(y);  // foo
            });
        }

    rangermap很多用法和rangeSet一样的

    /**
     * RangeMap描述了”不相交的、非空的区间”到特定值的映射。即 key是区间, value是值的map
     * 和RangeSet不同,RangeMap不会合并相邻的映射,即便相邻的区间映射到相同的值
    */
    @Test
    public void rangeMap(){
    RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
    rangeMap.put(Range.closed(1, 10), "foo");
    rangeMap.put(Range.open(3, 6), "bar");
    rangeMap.put(Range.open(10, 20), "foo");
    rangeMap.remove(Range.closed(5, 11));
    //根据区间里的任意值获取value
    rangeMap.get(1); //foo
        //获取map视图进行迭代
    rangeMap.asMapOfRanges().forEach((x,y)-> {
    System.out.println(x);  // [1..3]
    System.out.println(y);  // foo
    });
    }
  • 相关阅读:
    SQLite增删改查(自己写SQL语句)
    Why you have so few friends?
    android数据库SQLite简单测试
    C语言 stringcpy,stringcat,stringcmp实现
    python 日期和时间
    Python continue 语句
    Python break 语句
    Python 循环语句
    Python 条件语句
    Python比较运算符
  • 原文地址:https://www.cnblogs.com/houzheng/p/10915314.html
Copyright © 2011-2022 走看看