Guava中的集合(一)

Guava对jdk的集合进行了扩展。这也是Guava最常用的地方。

  • Guava不可变集合
  • 提供了一些新的集合
  • 提供了比jdk更加强大的工具类
  • 提供了扩展工具类

不可变集合,说起不可变集合,其实也就是不可变对象。所谓不可变对象,是指一个对象被创建后,它的状态就不能再改变了。其最大的特点就是具有很高的安全性。而不可变集合的优点主要有以下方面:

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

Guava提供了比jdk更加优秀的不可变集合,每种不可变集合都有3种创建方式,而且Guava也给每一种不可变集合提供了视图。我们在这里就用不可变的List来展示一下。
注:Guava的不可变集合是不支持null的。即Guava的不可变集合中是不能存储null。

        ArrayList list=new ArrayList();
        list.add("zhaotong1");
        list.add("zhaotong2");
        list.add("zhaotong3");
        System.out.println(list);
        //第一种创建方式
        ImmutableList list1=ImmutableList.copyOf(list);
        //第二种创建方式
        ImmutableList list2=ImmutableList.of("zhaotong","zhaotong1");
        System.out.println(list2);
        //第三种创建方式
        ImmutableList list3=ImmutableList.builder().add("ab").add("cd")
                .add("as","c","das").build();
        System.out.println(list3);
        //提供的视图
        ImmutableList list4=list3.asList();
        System.out.println(list4.get(4));

这就是Guava中为我们提供的不可变List,当然还有不可变Set,Map等。如果要创建 的是一个不可变的排序集合,那么创建时,会自动为其排序,即该集合在构造时就是有序的。而Guava为每个集合所提供的视图,比原有集合在效率等方面更加强大。

接下来我们看看Guava为我们提供的新的集合类型。
Multiset接口:它可以多次的添加元素,他是继承与jdk中Collection接口而不是Set接口,所以可以包含重复元素但并没有违反原有契约。这里我们就以HashMultiset来加以说明其用法。其实Muiltiset我们可以把他当做集合来看,也可当做map来看。从map角度看其键为实体,而值为实体的数量。
下面就是HashMultiset的一些初级使用。

        HashMultiset hset=HashMultiset.create();
        //添加元素 ,可以添加重复元素
        hset.add("zhaotong");
        hset.add("zhaotong");
        hset.add("zhaotong1");
        //返回一个迭代器
        Iterator itor=hset.iterator();
        
        //把其看作把Multiset看作Map时  E 代表实体类型,而值就是该元素的数量
        Set>  set=hset.entrySet();
        
        //
        System.out.println(hset.count("zhaotong"));

Multimap接口:我们可以利用guava提供的此接口,方便的将一个键映射到多个值。代码是最好的文档,下面我们就用ArrayListMultimap做一个简单的使用。

//Multimap接口  很容易把一个键映射到多个值
    
        ArrayListMultimap asm=ArrayListMultimap.create();
        List arr=Arrays.asList(1,2,3,4,5,6);
        // putAll(String key,Iterable values)
        asm.putAll("zhaotong", arr);
        asm.put("zhaoritian", 9999);
        asm.forEach(new BiConsumer() {

            @Override
            public void accept(String t, Integer u) {
                System.out.println(t+" "+u);
                
            }
        });
        System.out.println(asm.get("zhaotong"));

此外,Multimap 接口还给我们提供了视图。

Map> map=asm.asMap();

其运行结果如下:

Paste_Image.png

这里只是最简单的介绍一下此接口,如果想看更深层次的,请关注我的。
BiMap接口:其实BiMap接口主要是实现键值对的双向映射。这里我们需要保持键值都不能重复,我们这里用HashBiMap做个示例:

        BiMap bi=HashBiMap.create();
        bi.put("zhaotong", 1);
        String s=bi.inverse().get(1);
        System.out.println(s);

运行结果:

Paste_Image.png

这里的inverse()方法反转BiMap的键值映射,因此要保证值唯一。而其values方法也返回的是值的Set集合。

Set set=bi.values();

Table接口:你想使用多个键做索引的时候,你可能会用类似Map>的实现,这种方式很丑陋,使用上也不友好。Guava为此提供了新集合类型Table,它有两个支持所有类型的键:”行”和”列”。Table提供多种视图。
下面我们就是使用其实现类HashBasedTable来进行演示。

       //创建一个Table,其实键可以看成一个二维数组。第一个键为行,第二个为列
        Table table11=HashBasedTable.create();
        //往table中存入键值对
        table11.put("zt", "xyy", 1);
        table11.put("zt", "xyy1", 1);
        table11.put("zt1", "xyy1", 1);
        table11.put("zt2", "xyy1", 1);
        //以行为基础转化为map
        Map> map=table11.rowMap();
        System.out.println(map);
        //得到行所对应键的Set集合
        Set set=table11.rowKeySet();
        System.out.println(set);
        //得到列所对应键的Set集合
        Set s=table11.columnKeySet();
        System.out.println(s);
        
        //得到指定行所对应的键值对。
        Map map1=table11.row("zt");
        System.out.println(map1);
        
        //以列为基础得到map
        Map> map3=table11.columnMap();
        System.out.println(map3);
        
        //得到指定列所对应的键值对
        Map map4=table11.column("xyy1");
        System.out.println(map4);

以上代码运行结果:

Guava中的集合(一)_第1张图片
Paste_Image.png

ClassToInstanceMap:它的键是类型,而值是符合键所指类型的对象。
为了扩展Map接口,ClassToInstanceMap额外声明了两个方法:[T getInstance(Class)和[T putInstance(Class, T),从而避免强制类型转换,同时保证了类型安全。
示例如下:

       //创建一个对象
        ClassToInstanceMap cls=MutableClassToInstanceMap.create();
        //放入指定类型的实例
        cls.putInstance(Integer.class, Integer.valueOf(1));
        //取出指定类型的实例
        System.out.println(cls.getInstance(Integer.class));

RangeSet:RangeSet描述了一组不相连的、非空的区间。当把一个区间添加到可变的RangeSet时,所有相连的区间会被合并,空区间会被忽略。
示例代码如下:

        //数字区间
        RangeSet rs=TreeRangeSet.create();
        rs.add(Range.closed(0, 10));
        rs.add(Range.closed(11, 15));
        rs.add(Range.closed(1, 16));
        rs.add(Range.closedOpen(15, 20));
        System.out.println(rs);
        //字母区间
        RangeSet rs1=TreeRangeSet.create();
        rs1.add(Range.closed("a", "d"));
        rs1.add(Range.closed("h", "y"));
        rs1.add(Range.closed("aa", "ac"));
        System.out.println(rs1);
        
        //视图,RangeSet提供了非常强大的视图
        
        //返回RangeSet的补集视图
        RangeSet rsc=rs.complement();
        
        System.out.println(rsc);// 输出结果:[(-∞..0), [20..+∞)]
        
        //返回RangeSet的交集集合
        RangeSet rsubr=rs.subRangeSet(Range.closed(15, 50));
        System.out.println(rsubr);//输出结果:[[15..20)]
        
        //Set>表现RangeSet,这样可以遍历其中的Range
        rs.add(Range.closed(30, 50));
        Set> rsset=rs.asRanges();
        System.out.println(rs.asRanges()); //输出结果:[[0..20), [30..50]]
        
        //RangeSet 有很多查询方法,包括:contains(C)//是否包含给定元素,rangeContaining(C)//是否包含给定元素的区间,encloses(Range)://是否有包含给定区间的区间
        //返回包括所有区间的最小区间
        Range ri= rs.span();
        System.out.println(ri);//输出结果:      [0..50]
  • RangeMap:”不相交的、非空的区间”到特定值的映射.
    示例代码如下:
        RangeMap rm=TreeRangeMap.create();
        //区间作为键不能相同
        rm.put(Range.closed(10, 19), "zhaotong");
        rm.put(Range.open(10, 19),"zhaotong1");
        rm.put(Range.closed(19,34),"zhaotong2");
        System.out.println(rm);//输出结果:[[10..10]=zhaotong, (10..19)=zhaotong1, [19..34]=zhaotong2]
        
        //提供的视图
        Map,String> map=rm.asMapOfRanges();
        System.out.println(map);//输出结果:{[10..10]=zhaotong, (10..19)=zhaotong1, [19..34]=zhaotong2}
        //返回与指定区间的交集
        RangeMap rms= rm.subRangeMap(Range.closed(10, 10));
        System.out.println(rms);//输出结果:{[10..10]=zhaotong}

你可能感兴趣的:(Guava中的集合(一))