guava-新集合类型

新集合类型

guava初探-学习目录

Multiset
  • 这里的集合[set]是数学上的概念.
  • Multiset继承自JDK中的Collection接口,而不是Set接口,所以包含重复元素并没有违反原有的接口契约

先来一个实例,统计单词出现的次数java中的一般做法

    @Test
    public void testDemo() {
        List<String> list = new ArrayList<>();
        list.add("zs");
        list.add("zs");
        list.add("ls");
        list.add("ww");
        list.add("mz");
        list.add("ls");
        Map<String, Integer> c = new HashMap<>();
        for (String word : list) {
            Integer count = c.get(word);
            c.put(word, (count == null) ? 1 : count + 1);
        }
        System.out.println("zs出现的次数: " + c.get("zs"));
    }
使用Multiset
    @Test
    public void testMultiset() {
        List<String> list = new ArrayList<>();
        list.add("zs");
        list.add("zs");
        list.add("ls");
        list.add("ww");
        list.add("mz");
        list.add("zs");
        Multiset<String> multiset = HashMultiset.create(list);
        System.out.println("zs出现的次数: "+multiset.count("zs"));
    }
常用的方法
方法描述
count(E)指定元素的数量(例子中使用的方法)
size返回集合元素的总个数(包括重复的元素)
elementSet()Multiset中不重复元素的集合,类型为Set
entrySet()和Map的entrySet类似,返回Set<Multiset.Entry>,其中包含的Entry支持getElement()和getCount()方法
retainAll(Collectionc)保留出现在给定集合参数的所有的元素
removeAll(Collectionc)去除出现给给定集合参数的所有的元素
add(E, int)增加给定元素在Multiset中的计数
remove(E,int)减少给定元素在Multiset中的计数
setCount(E, int)设置给定元素在Multiset中的计数(不可以为负数)
example
    @Test
    public void testMultiset() {
        List<String> list = new ArrayList<>();
        list.add("zs");
        list.add("zs");
        list.add("ls");
        list.add("ww");
        list.add("mz");
        list.add("zs");
        Multiset<String> multiset = HashMultiset.create(list);

        //count(E)
        System.out.println("zs出现的次数: "+multiset.count("zs"));

        //size
        System.out.println("multiset集合的个数: "+multiset.size());

        //elementSet()
        Set<String> set = multiset.elementSet();
        System.out.println("multiset去重后的元素集合: "+set);

        //entrySet()
        Set<Multiset.Entry<String>> entries = multiset.entrySet();
        for (Multiset.Entry<String> entry : entries){
            System.out.println("单词: "+entry.getElement()+"出现的次数为: "+entry.getCount());
        }

        //removeAll(Collectionc)
        multiset.removeAll(Arrays.asList("li"));
        System.out.println("multiset集合的元素: "+multiset);

        //retainAll(Collectionc)
        multiset.retainAll(Arrays.asList("zs"));
        System.out.println("multiset集合的元素: "+multiset);

        //add(E, int)
        multiset.add("ww",100);
        System.out.println("multiset集合的元素: "+multiset);

        //remove(E,int)
        multiset.remove("ww",10);
        System.out.println("multiset集合的元素: "+multiset);

        //setCount(E, int)
        multiset.setCount("ww",0);
        System.out.println("multiset集合的元素: "+multiset);
    }

上面我们讲述的是Multiset的HashMap实现

Multimap

先看一个实例: 用户信息根据年龄分组下面值一般的做法

public class GuavaMultiMapTest {
    @Test
    public void MultiMap() {
        List<User> userList = new ArrayList<>();//假设是已经获取的用户信息集合
        Map<String, List<User>> map = new HashMap<>();
        List<User> temp = null;
        for (User user : userList) {
            temp = map.get(user.getAge());
            if (temp == null) {
                temp = new ArrayList<>();
                temp.add(user);
            }
            temp.add(user);
        }
    }
}

class User {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

Multimap的实现(当然如果用java8 流实现也是可以的!)
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class GuavaMultiMapTest {
    @Test
    public void MultiMap() {
        List<User> userList = new ArrayList<>();//假设是已经获取的用户信息集合
        Multimap<Integer, User> multimap = HashMultimap.create();
        for (User user : userList) {
            multimap.put(user.getAge(),user);
        }
    }
}

class User {
    private String name;
    private Integer age;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
常用的方法
方法描述
get(K)集合形式返回键所对应的值
put(K, V)添加单个值
putAll(K, Iterable)添加多个值
remove(K, V)移除键对应值
removeAll(K)清除键对应的所有值,返回的集合包含所有之前映射到K的值,但修改这个集合就不会影响Multimap了。
replaceValues(K, Iterable)清除键对应的所有值,并重新把key关联到Iterable中的每个元素。返回的集合包含所有之前映射到K的值
asMap()
Bimap

提供了key和value的双向关联的数据结构
1.假设我们需要通学生的姓名找到学号(这种普通的map可以实现)

    @Test
    public void logMapTest() {
        Map<Integer, String> sMap = Maps.newHashMap();
        sMap.put(1, "zs");
        sMap.put(2, "li");
        sMap.put(3, "ww");
        //找到一号学生的名字
        System.out.println(sMap.get(1));
    }

2.还希望通过名字(假设名字唯一)找到工号
一般的做法是把map反转并保存

    @Test
    public void logMapTest() {
        Map<Integer, String> sMap = new HashMap<>();
        sMap.put(1, "zs");
        sMap.put(2, "li");
        sMap.put(3, "ww");
        //找到一号学生的名字
        System.out.println(sMap.get(1));

        //反向保存
        Map<String, Integer> inverseMap = new HashMap<>();
        for(Map.Entry<Integer,String> entry: sMap.entrySet()) {
            inverseMap.put(entry.getValue(), entry.getKey());
        }
        //找到'zs'学生的学号
        System.out.println(inverseMap.get("zs"));
    }
guava 的BiMap实现
    @Test
    public void testBiMap() {
        BiMap biMap = HashBiMap.create();
        biMap.put(1, "zs");
        biMap.put(2, "li");
        biMap.put(3, "ww");
        //找到一号学生的名字
        System.out.println(biMap.get(1));
        
        //map键值对反向转换
        BiMap inverseMap = biMap.inverse();

        //找到'zs'学生的学号
        System.out.println(inverseMap.get("zs"));
    }
BiMap的实现种类
键–值实现对应的BiMap实现
HashMapHashBiMap
ImmutableMapImmutableBiMap
EnumMapEnumBiMap
EnumMapHashMap
guava table

guava table 提供了多个索引的接口Table<R, C, V>
常见的常见包含: 保存一个班学生的成绩分数

    @Test
    public void testTable(){
        //保存课程和分数
        Table<String,String,Integer> table = HashBasedTable.create();
        table.put("zs","java",100);
        table.put("li","java",80);
        table.put("ww","vue",95);
        table.put("ww","java",50);
        table.put("li","vue",60);
        table.put("zs","vue",40);
        //获取zs的java分数
        System.out.println("zs的就java分数:"+table.get("zs","java"));
    }

这里的2个键值其实就是行key®列key©

常用的方法和实现
方法描述
rowKeySet()得到所有的Rkey集合
rowMap()返回一个Map<R, Map<C, V>>的视图
row®用Map<C, V>返回给定”行”的所有列,对这个map进行的写操作也将写入Table中
cellSet()类似于Map.Entry但它是用行和列两个键区分的
columnKeySet()得到所有的列key
columnMap()返回一个Map<C, Map<R, V>>的视图
row®用Map<C, V>返回给定”行”的所有列,对这个map进行的写操作也将写入Ta
column©用Map<R, V>返回给定”列”的所有行,对这个map进行的写操作也将写入Table中

例子

    @Test
    public void testGuavaTable() {
        //保存课程和分数
        Table<String, String, Integer> table = HashBasedTable.create();
        table.put("zs", "java", 100);
        table.put("li", "java", 80);
        table.put("ww", "vue", 95);
        table.put("ww", "java", 50);
        table.put("li", "vue", 60);
        table.put("zs", "vue", 40);

        //rowKeySet 获取的素有的学生姓名(行key))
        Set<String> nameSet = table.rowKeySet();
        System.out.println("班级所有学生的姓名: " + nameSet);

        //columnKeySet 获取班级学生的考试的课程(列key)
        Set<String> courseSet = table.columnKeySet();
        System.out.println("班级学生考试的课程: " + courseSet);

        //rowMap() 获取班级学生每个课程的成绩
        Map<String, Map<String, Integer>> nameMap = table.rowMap();
        System.out.println("班级学生每个课程的成绩: " + nameMap);

        //columnMap() 获取班级课程每个学生的成绩
        Map<String, Map<String, Integer>> courseMap = table.columnMap();
        System.out.println("班级个课程每个学生的成绩: " + courseMap);

        //row(r) 获取学生zs的所有课程成绩
        Map<String, Integer> zsScoreMap = table.row("zs");
        System.out.println("获取指定学生的所有课程的成绩: "+zsScoreMap);

        //row(r) 获取学生zs的所有课程成绩
        Map<String, Integer> coreMap = table.column("vue");
        System.out.println("获取指定课程所有学生的成绩: "+coreMap);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值