高质量的Google Guava库

高质量的GoogleGuava库

GoogleGuava 辅助库是java1.6及以上的类库集合的扩展项目
里面包含大量高质量的 API 可以使你的Java代码更加优雅,更加简洁,让你工作更加轻松愉悦
本文章主要向大家介绍guava库的基本使用和小编抽取的一些不错操作

先上jar包下载地址

Guava 流畅的基本工具 Basic utilities

  • Optional 使用和避免null

    Optional小编觉得更重要的不是代码本身 而是给程序员一种神经提示 进而带动程序员积极思考引用缺失的问题
    • 由于基本工具所要举得例子不是很多 在此小编直接贴入网址在这里会有更好的对Guava基本工具的解析
    • https://wiki.jikexueyuan.com/...

Guava 对集合的强力扩展 collect

Guava对已有集合的能力增强

  • 可变集合的创建 Lists、Sets、Maps、Collections2

    针对jdk中已存在的集合建立的工具类
//jdk中的普通方式
Map mp=new HashMap<>();
//Guava中的方式
List list = Lists.newArrayList();
Set set = Sets.newHashSet();
Map map = Maps.newHashMap();
//当然也可以利用静态导入的方式让代码更简单
List list = newArrayList();
//关于Eclipse中设置静态导入在文章结尾会跟大家介绍
  • 不可变集合的创建 ImmutableCollection、ImmutableMap

    在多线程操作下,是线程安全的
    比可变集合更有效的利用资源
    中途不能添加或更改元素
    通常我们需要一个测试集合的时候便可以用到此接口
    ps: jdk9也已经实现类似方法
var list=ImmutableList.of("1","2","3","4");
var set=ImmutableSet.of("a", "b", "c", "d");
var map=ImmutableMap.of("key1", "value1", "key2", "value2");
//jdk9中的创建不可变集合的方式也很简单
List.of("Hello", "World");
Set.of("Hello", "World");
Map.of("Hello", 1, "World", 2);
  • 更智能的ImmutableXXX.copyOf
    会尝试在安全的时候避免做拷贝——实际的实现细节不详,但通常来说是很智能的
  • 关于不可变并且有序集合ImmutableSortedxxx
var set=ImmutableSortedSet.of(2,1,3,2,5,4);
out.println(set);
//1,2,3,4,5   排序并且排重

Guava中新增的牛X集合

  • Multiset

    可以用两种方式看待 Multiset:

    • 没有元素顺序限制的 ArrayList
    • Map,键为元素,值为计数

    Multiset 没有继承Set接口 不等于Set
    常用 Multiset 接口的实现类有:

    • HashMultiset: 元素存放于 HashMap
    • LinkedHashMultiset: 元素存放于 LinkedHashMap,即元素排列顺序由第一次放入的顺序决定
    • TreeMultiset:元素被排序存放于TreeMap
    • EnumMultiset: 元素必须是 enum 类型
    • ImmutableMultiset: 不可修改的 Mutiset

    Multiset接口定义的抽象方法主要有:

    • 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。包含的Entry支持使用getElement()和getCount()
    • setCount(E element ,int count): 设定某一个元素的重复次数
    • setCount(E element,int oldCount,int newCount): 将符合原有重复个数的元素修改为新的重复次数
    • retainAll(Collection c) : 保留出现在给定集合参数的所有的元素 
    • removeAll(Collectionc) : 去除出现在给定集合参数的所有的元素
HashMultiset multiSet = HashMultiset.create(); 
multiSet.add("1");
multiSet.add("1");
multiSet.add("2");
multiSet.add("3", 3);
out.println(multiSet.count("1")+"次");
//2次
out.println(multiSet);
//[1 x 2, 2, 3 x 3]
out.println("元素个数"+multiSet.size());
//元素个数6
  • 如果看过我Stream介绍那篇文章的小伙伴也会想到用MultiSet来计算字符串中的元素出现个数 哈哈哈
//题目是 求出字符串中的元素出现的个数 
利用MultiSet可想而知一定很简单 我们只要处理一下重复元素就好
那么我们便可用Stream的知识简单的处理重复元素:
Multiset create = HashMultiset.create();
//依旧我们不给出字符串到集合的转换 大家总要消化下新知识嘛
create.addAll(List.of("1", "2", "1","q","b","1","z","z"));
利用Stream进行遍历 即排除了重复元素 又能正确的遍历结果 不伤害原集合
create.stream()
      .distinct().sorted()
      .forEach((s)->out.println(s+"出现次数"+create.count(s)));
//1出现次数3
//2出现次数1
//b出现次数1
//q出现次数1
//z出现次数2
ps 千万不要过于满足 应为我们还有更好的办法 
 
  • MultiMap

    ps:不是Map
    可以用两种方式思考 Multimap 的概念:

    • ”键-单个值映射”的集合:
      a -> 1 a -> 2 a ->4 b -> 3 c -> 5
    • 或者”键-值集合映射”的映射:
      a -> [1, 2, 4] b -> 3 c -> 5

      常用实现类:
      在大多数要使用 Map的地方,你都可以使用它们:
实现类 键行为对应的集合 值行为对应的集合
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap LinkedHashMap LinkedList
LinkedHashMultimap LinkedHashMap LinkedHashMap
TreeMultimap TreeMap TreeSet
ImmutableSetMultimap ImmutableMap ImmutableSet
 List list = newArrayList();
         list.add(4);
         list.add(5);
         list.add(6);
ListMultimap Multimap =ArrayListMultimap.create();
         Multimap.put("1",1);
         Multimap.put("1",2);
         Multimap.put("1",3);
         Multimap.putAll("2",list);
out.println(Multimap);
//{1=[1, 2, 3], 2=[4, 5, 6]}
  • BiMap 键值双向映射的map

    • 可以用 inverse()反转 BiMap的键值映射
    • 保证值是唯一的,因此 values()返回 Set 而不是普通的 Collection
键-值实现 值-键实现 对应的BiMap实现
HashMap HashMap HashBiMap
ImmutableMap ImmutableMap ImmutableBiMap
EnumMap EnumMap EnumBiMap
EnumMap HashMap EnumHashBiMap
BiMap biMap = HashBiMap.create();
         biMap.put(1, "1");
         biMap.put(4, "2");
         biMap.put(3, "3");
         //添加已有的值将新键覆盖旧键 forcePut
         biMap.forcePut(2, "2");
out.println(biMap);//{1=1, 3=3, 2=2}
//将键值切换映射 inverse
var biMap2 = bimap.inverse();
out.println(biMap2.get("1"));//1
  • Table 多键检索的Map

    • 它有两个支持所有类型的键:”行”和”列”。
    • Table 提供多种视图,以便从各种角度使用它

    常用实现类:

    • HashBasedTable:本质上用 HashMap>实现;
    • TreeBasedTable:本质上用 TreeMap>实现;
    • ImmutableTable:本质上用 ImmutableMap>实现;注:ImmutableTable 对稀疏或密集的数据集都有优化。
    • ArrayTable:要求在构造时就指定行和列的大小,本质上由一个二维数组实现,以提升访问速度和密集 Table 的内存利用率。ArrayTable 与其他 Table 的工作原理有点不同,请参见 Javadoc 了解详情。
Table table = HashBasedTable.create();
         table.put(1, "Asen", "百万");
         table.put(1, "Bsen", "百万");
         table.put(2,"Bsen","千万");
//双键查值
out.println(table.get(2, "Bsen"));
//行视图
out.println(table.row(1));
{Asen=百万, Bsen=百万}
//列视图
out.println(table.column("Bsen"));
{1=百万, 2=千万}

Guava对字符串的处理

小编这里额外说明一下:关于对字符串的处理小编觉得Guava是最棒的 综合性能更是没话说 下面各位慢慢欣赏
  • Joiner 连接器

  • join 拼接集合中的元素
String join = Joiner.on("-_-").join(List.of("1", "2","3","4"));
//比stream先进的是  此方法可以支持任意类型  stream针对字符串之外还要先进行处理
String join2 = Joiner.on("-_-").join(List.of(5,6,7,8));
out.println(join);
//1-_-2-_-3-_-4
out.println(join2);
//5-_-6-_-7-_-8
  • skipNullls 过滤null
String join3 = Joiner.on("~_~")
                     .skipNulls()
                     .join("1",null,"2","3");
out.println(join3);//1~_~2~_~3
  • useForNull 替换null
String join4 = Joiner.on("~_~")
                     .useForNull("空")
                     .join("1",null,"2","3");
out.println(join4);//1~_~空~_~2~_~3
  • withKeyValueSeparator 拼接Map中元素
//此时的字符串拼接则将Map中一个键值对看为一个整体 进行拼接
String join5 = Joiner.on("~_~")
.withKeyValueSeparator("值:")
.join(Map.of(1,10,2,20));
out.println(join5);//1值:10~_~2值:20
  • Splitter 字符分割

  • split、splitToList 根据指定字符分割字符串,并转集合
Iterable split = Splitter.on(";")
                                 .split("12;34;56;7");
split.forEach(out::println);
//12 34 56 7
// ps: 如果找不到指定字符则返回原字符串
  • trimResults 将指定charmatcher转空串
List splitToList = Splitter.on(";")
                                   .trimResults(CharMatcher.anyOf("a"))
                                   .splitToList("aa;b");
// [, b]
  • limit 指定分割个数
List list=Splitter.on(";")
                          .limit(2)
                          .splitToList("a;b;c");
//a  b;c
List list=Splitter.on(";")
                          .limit(3)
                          .splitToList("a;b;c");
//a    b   c
  • withKeyValueSeparator 转为Map
 Map split3 = Splitter.on(";")
                                      .withKeyValueSeparator("-")
                                      .split("a-10;b-20");
split3.forEach((k,v)->out.println(k+"="+v));
//a=10    b=20
  • CharMatcher 字符匹配器

    根据要求获取匹配器类型:
    ANY: 匹配任何字符
    ASCII: 匹配是否是ASCII字符
    BREAKING_WHITESPACE: 匹配所有可换行的空白字符(不包括非换行空白字符,例如"\u00a0")
    DIGIT: 匹配ASCII数字 
    INVISIBLE: 匹配所有看不见的字符
    JAVA_DIGIT: 匹配UNICODE数字, 使用 Character.isDigit() 实现
    JAVA_ISO_CONTROL: 匹配ISO控制字符, 使用 Charater.isISOControl() 实现
    JAVA_LETTER: 匹配字母, 使用 Charater.isLetter() 实现
    JAVA_LETTER_OR_DIGET: 匹配数字或字母
    JAVA_LOWER_CASE: 匹配小写
    JAVA_UPPER_CASE: 匹配大写
    NONE: 不匹配所有字符
    SINGLE_WIDTH: 匹配单字宽字符, 如中文字就是双字宽
    WHITESPACE: 匹配所有空白字符
    anyOf(CharSequence): 枚举匹配字符 如anyOf("aeiou")匹配小写英语元音
    is(char): 给定单一字符匹配
    inRange(char,char): 给定字符范围匹配 如inRange('a','z')
    对获取到的匹配器进行处理:
    collapseFrom(CharSequence,   char) 把每组连续的字符替换为指定字符
    matchesAllOf(CharSequence) 测试是否字符序列中的所有字符都匹配。
    removeFrom(CharSequence) 从字符序列中移除所有匹配字符。
    retainFrom(CharSequence) 在字符序列中保留匹配字符,移除其他字符。
    trimFrom(CharSequence) 移除字符序列的前导匹配字符和尾部匹配字符。
    replaceFrom(CharSequence,   CharSequence) 用特定字符序列替代匹配字符。
    更多方法还请参考: https://www.cnblogs.com/amei0...
//两个简单的栗子:
//求出字符串中英文字母的个数
var string="ab2dA-+=wq1c390";
var vstr=CharMatcher.JAVA_LETTER.retainFrom(string);
out.println(vstr);//abdAwqc
//过滤掉字符串中的数字
var string="12345hello90word";
var vint=CharMatcher.inRange('0', '9').removeFrom(string);
out.println(vstr);//helloword
//将字符串中任意长度空格用指定字符代替
String rs = CharMatcher
            .whitespace()
            .collapseFrom("42d3   gfsdg4f afdasf        dasf3f  ",'、');

关于Eclipse 静态导包问题

静态导包显然能让代码显得更简洁干练
下面具体说明EclipseMyEclipse如何设置指定静态导包
  • 确认开启静态导入选项 Window->Preferences->Java->Editor->Content Assist页面选中Use static imports
    高质量的Google Guava库_第1张图片
  • 新键默认静态导入字段 Window->Preferences->Java->Editor->Content Assist->Favorites
    高质量的Google Guava库_第2张图片
  • 使用方法:
    快捷键导入还是不会导入静态字段的 这时候我们要手动敲出比如out 然后ALT+/ 提示选项第一个就是自动补全加默认静态导包了

你可能感兴趣的:(java)