美文网首页
guava集合

guava集合

作者: 扎Zn了老Fe | 来源:发表于2023-03-18 23:33 被阅读0次

    ImmutableSet && ImutableMap

    不可变对象有很多优点,包括:

    • 当对象被不可信的库调用时,不可变形式是安全的;
    • 不可变对象被多个线程调用时,不存在竞态条件问题
    • 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
    • 不可变对象因为有固定不变,可以作为常量来安全使用。

    创建对象的不可变拷贝是一项很好的防御性编程技巧。Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本。

    示例
    package guava.collect;
    
    import com.google.common.collect.ImmutableSet;
    
    /**
     * @author denny
     * @Description 不可变集合
     * @date 2018/7/26 下午3:16
     */
    public class ImmutableCollectionsTest {
        /**
         * 1.直接申明静态集合
         */
        public static final ImmutableSet<String> COLOR_NAMES_1 = ImmutableSet.of(
            "red",
            "orange",
            "yellow",
            "green");
        /**
         * 2.防御式copy
         */
        public static final ImmutableSet<String> COLOR_NAMES_2 = ImmutableSet.copyOf(COLOR_NAMES_1);
    
        /**
         * 3.builder建造者模式
         */
        public static final ImmutableSet<String> COLOR_NAMES_3 = ImmutableSet.<String>builder().addAll(COLOR_NAMES_2).add("blue").build();
    
    
        public static void main(String[] args) {
            System.out.println("of:"+COLOR_NAMES_1);
            System.out.println("防御式copy:"+COLOR_NAMES_2);
            System.out.println("建造者模式:"+COLOR_NAMES_3);
            System.out.println("转换成list:"+COLOR_NAMES_3.asList());
        }
    }
    /*** 运行结果
    *of:[red, orange, yellow, green]
    *防御式copy:[red, orange, yellow, green]
    *建造者模式:[red, orange, yellow, green, blue]
    *转换成list:[red, orange, yellow, green, blue]
    ***/
    

    Multiset

    可以多次添加相等的元素,它和set最大的区别就是它可以对相同元素做一个计数的功能。
    数据类型

    abstract class AbstractMapBasedMultiset {
        private transient Map<E, Count> backingMap;
    }
    

    可以看到,Multiset是一个Map类型,它的value值记录了这个key出现了多少次。

    实现类
    Map Multiset 是否支持null
    HashMap HashMultiset
    TreeMap TreeMultiset
    LinkedHashMap LinkedHashMultiset
    EnumMultiset
    ImmutableMap ImmutableMultiset
    ConcurrentHashMap ConcurrentMultiset
    方法
    方法 描述
    add(E element) 向其中添加单个元素
    add(E element,int occurrences) 向其中添加指定个数的元素
    count(Object element) 返回给定参数元素的个数
    remove(E element) 移除一个元素,其count值 会响应减少
    remove(E element,int occurrences) 移除相应个数的元素
    elementSet() 将不同的元素放入一个Set中
    entrySet() 类似与Map.entrySet 返回Set<Multiset.Entry>。包含的Entry支持使用getElement()和getCount()
    setCount(E element ,int count) 设定某一个元素的重复次数
    setCount(E element,int oldCount,int newCount) 将符合原有重复个数的元素修改为新的重复次数
    retainAll(Collection c) 保留出现在给定集合参数的所有的元素
    removeAll(Collectionc) 去除出现给给定集合参数的所有的元素
    size() 这个集合的大小,包含重复元素
    示例
    import com.google.common.collect.HashMultiset;
    import com.google.common.collect.Multiset;
    
    public class MultisetTest {
    
        public static void main(String[] args) {
    
            String str = "张三 李四 李四 王五 王五 王五";
            String[] strArr = str.split(" ");
    
            List<String> words = new ArrayList<String>(Arrays.asList(strArr));
    
            //创建一个HashMultiset集合,并将words集合数据放入
            Multiset<String> wordMultiset = HashMultiset.create();
            wordMultiset.addAll(words);
    
            //将不同的元素放在一个集合set中
            for (String key : wordMultiset.elementSet()) {
                //查看指定元素的个数
                System.out.println(key + "-->" + wordMultiset.count(key));
            }
    
            System.out.println("---------向集合中添加元素----------");
            //向集合中添加元素
            wordMultiset.add("李四");
            for (String key : wordMultiset.elementSet()) {
                System.out.println(key + "-->" + wordMultiset.count(key));
            }
    
            System.out.println("-------向集合中添加若干个元素------");
            //向集合中添加若干个元素
            wordMultiset.add("赵六", 10);
            for (String key : wordMultiset.elementSet()) {
                System.out.println(key + "-->" + wordMultiset.count(key));
            }
    
            System.out.println("--------向集合中移出一个元素------");
            //向集合中移出一个元素
            wordMultiset.remove("张三");
            for (String key : wordMultiset.elementSet()) {
                System.out.println(key + "-->" + wordMultiset.count(key));
            }
    
            System.out.println("------向集合中移出若干个元素------");
            //向集合中移出若干个元素,如果元素的个数小于要移除的个数,则会把该元素移除光
            wordMultiset.remove("赵六",5);
            for (String key : wordMultiset.elementSet()) {
                System.out.println(key + "-->" + wordMultiset.count(key));
            }
    
    
            System.out.println("-----设定某一个元素的重复次数-----");
            //设定某一个元素的重复次数
            wordMultiset.setCount("张三", 10);
            for (String key : wordMultiset.elementSet()) {
                System.out.println(key + "-->" + wordMultiset.count(key));
            }
    
            System.out.println("-----设置复合元素的个数设为新的重复次数-----");
            //设置复合元素的个数设为新的重复次数(条件是第二个参数的数量要是实际数量一致,否则无效)
            wordMultiset.setCount("and", 1,0);
            for (String key : wordMultiset.elementSet()) {
                System.out.println(key + "-->" + wordMultiset.count(key));
            }
    
            System.out.println("-------删除给定集合中的元素------");
            //删除给定集合中的元素
            wordMultiset.removeAll(words);
            for (String key : wordMultiset.elementSet()) {
                System.out.println(key + "-->" + wordMultiset.count(key));
            }
        }
    }
    

    Multimap

    multimap和MultiSet的继承结果很相似,只不过在上层的接口是Multimap不是Multiset。

    Multimap的特点其实就是可以包含有几个重复Key的value,你可以put进入多个不同value但是相同的key,但是又不是让后面覆盖前面的内容。

    它的业务场景:当你需要构造像Map<K, List<V>>或者Map<K, Set<V>>这样比较复杂的集合类型的数据结构,来做相应的业务逻辑处理。那Multimap在合适不过。

    实现类
    Implementation Keys 的行为类似 Values的行为类似
    ArrayListMultimap HashMap ArrayList
    HashMultimap HashMap HashSet
    LinkedListMultimap LinkedHashMap* LinkedList*
    LinkedHashMultimap LinkedHashMap LinkedHashSet
    TreeMultimap TreeMap TreeSet
    ImmutableListMultimap ImmutableMap ImmutableList
    ImmutableSetMultimap ImmutableMap ImmutableSet
    方法
    方法 描述
    put(K, V)
    putAll(K, Iterable<V>)
    remove(K, V)
    removeAll(K)
    replaceValues(K, Iterable<V>)
    asMap() 提供Map<K,Collection>形式的视图
    entries() 提供Collection<Map.Entry<K, V>>的视图(对SetMultimap,返回的是Set)
    keySet() 用Set表示Multimap中所有不同的键
    keys() 用Multiset表示Multimap中的所有键
    values() 提供Collection包含Multimap中的所有值
    示例
    public class MultimapTest {
    
    
            public static void main(String args[]){
    
                  Multimap<String,String> multimap = ArrayListMultimap.create();
    
                multimap.put("lower", "a");
                multimap.put("lower", "b");
                multimap.put("lower", "c");
    
                multimap.put("upper", "A");
                multimap.put("upper", "B");
    
                List<String> lowerList = (List<String>)multimap.get("lower");
                //输出key为lower的list集合
                System.out.println("输出key为lower的list集合=========");
                System.out.println(lowerList.toString());
                lowerList.add("f");
                System.out.println(lowerList.toString());
    
    
                Map<String, Collection<String>> map = multimap.asMap();
                System.out.println("把Multimap转为一个map============");
                for (Map.Entry<String,  Collection<String>> entry : map.entrySet()) {
                    String key = entry.getKey();
                    Collection<String> value =  multimap.get(key);
                    System.out.println(key + ":" + value);
                }
    
                System.out.println("获得所有Multimap的key值==========");
                Set<String> keys =  multimap.keySet();
                for(String key:keys){
                    System.out.println(key);
                }
    
                System.out.println("输出Multimap所有的value值========");
                Collection<String> values = multimap.values();
                System.out.println(values);
            }
    }
    /**输出结果:
     *输出key为lower的list集合=========
     * [a, b, c]
     * [a, b, c, f]
     * 把Multimap转为一个map============
     * lower:[a, b, c, f]
     * upper:[A, B]
     * 获得所有Multimap的key值==========
     * lower
     * upper
     * 输出Multimap所有的value值========
     * [a, b, c, f, A, B]
      */
    

    Table

    结构类似于二维数组,它有两个支持所有类型的键:”行”和”列”。

    bidirectional maps

    bimap的作用很清晰:它是一个一一映射,可以通过key得到value,也可以通过value得到key。与HashMap对比,不仅key能保证唯一,value也能保证唯一。

    实现类
    Implementation Keys 的行为类似 Values的行为类似
    HashBiMap HashMap HashMap
    EnumBiMap Enum Enum
    ImmutableBiMap
    方法
    方法 描述
    inverse key, value反转
    示例
    public class bimapTest {
            public static void main(String args[]){
    
                //双向map
                BiMap<Integer,String> biMap = HashBiMap.create();
                biMap.put(1,"张三");
                biMap.put(2,"李四");
                biMap.put(3,"王五");
                biMap.put(4,"赵六");
                biMap.put(5,"李七");
                biMap.put(4,"小小");
    
                //通过key值得到value值(注意key里面的类型根据泛行
                String value = biMap.get(1);
                System.out.println("id为1的value值 --"+value);
    
                //通过value值得到key值
                int key = biMap.inverse().get("张三");
                System.out.println("张三key值 --"+key);
    
                //通过key值重复,那么vakue值会被覆盖。
                String valuename = biMap.get(4);
                System.out.println("id为4的value值 --"+valuename);
            }
    }
    /*运行结果:
     *id为1的value值 --张三
     *张三key值 --1
     *id为4的value值 --小小
     */
    

    参考:
    [1]. https://www.cnblogs.com/qdhxhz/p/9410898.html
    [2]. https://www.cnblogs.com/qdhxhz/p/9411511.html
    [3]. https://www.cnblogs.com/qdhxhz/p/9425039.html

    相关文章

      网友评论

          本文标题:guava集合

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