java代码之美(2)
guava 复写Object常用方法
Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,这个库提供用于集合,缓存,支持原语,并发性,常见注解,字符串处理,I/O和验证的实用方法。
这些高质量的 API 可以使你的Java代码更加优雅,更加简洁,让你工作更加轻松愉悦。
一、概述
在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals,hashCode和toString等方法。每次写这几个方法都要做很多重复性的判断,
很多类库提供了覆写这几个方法的工具类, Guava也提供了类似的方式。下面我们来看看Guava中这几个方法简单使用。
Guava中Objects类提供了很多和Object类作用相同、效率更高的方法可供使用:
1、equal方法
使用Obejct的equals方法进行相等判断,例如:test.equals("test");如果test为null,则会发生NullPointerException,Objects的equal方法可以帮助你
避免NullPointerException,它的判断逻辑是这样的:return a == b || (a!=null&& a.equals(b));所以,可以很放心的使用,Objects.equal(test,"test")
当然在JDK7中也提供了同样判断逻辑的方法:Objects.equals(test,"test");

public class ObjectTest {
@Test
public void equalTest() {
System.out.println(Objects.equal("a", "a"));
System.out.println(Objects.equal(null, "a"));
System.out.println(Objects.equal("a", null));
System.out.println(Objects.equal(null, null));
}
}
/**输出结果
* true
* false
* false
* true
*/

2、hashCode方法
对于hashCode首先要明白两点:
1、如果equals()判断两个对象相等,那么它们的hashCode()方法一定返回同样的值。
2、并没有强制要求如果equals()判断两个对象不相等,它们的hashCode可以相同也可以不同。
Guava提供给我们了一个更加简单的方法--Objects.hashCode(Object ...), 这是个可变参数的方法,参数列表可以是任意数量,所以可以像这样
使用Objects.hashCode(field1, field2, ...,fieldn)。非常方便和简洁。

import org.junit.Test;
import com.google.common.base.Objects; public class ObjectTest {
@Test
public void hashcodeTest() {
System.out.println(Objects.hashCode("a"));
System.out.println(Objects.hashCode("a"));
System.out.println(Objects.hashCode("a","b"));
System.out.println(Objects.hashCode("b","a"));
System.out.println(Objects.hashCode("a","b","c")); Person person=new Person("peida",23);
System.out.println(Objects.hashCode(person));
System.out.println(Objects.hashCode(person));
}
} class Person {
public String name;
public int age; Person(String name, int age) {
this.name = name;
this.age = age;
}
}


//输出结果
128
4066
4096
126145
19313256
19313256

3、toStringHelper()方法
因为每个类都直接或间接地继承自Object,因此每个类都有toString()方法。这个方法是用得最多的, 覆写得最多, 一个好的toString方法对于调试来说是非常重要的,
但是写起来确实很不爽。Guava也提供了toString()方法。
通过toStringHelper方法来输出你需要输出的属性字段

import org.junit.Test;
import com.google.common.base.Objects; public class ObjectTest { @Test
public void toStringTest() {
//this代表当前类,这里只输出x一个属性字段
System.out.println(Objects.toStringHelper(this).add("x", 1).toString()); //代表输出对象为Person对象
System.out.println(Objects.toStringHelper(Person.class).add("x", 1).toString()); //add可以叠加
Person person=new Person("peida",23);
String result = Objects.toStringHelper(Person.class).add("name", person.name).add("age", person.age).toString();
System.out.print(result);
}
}
class Person {
public String name;
public int age; Person(String name, int age) {
this.name = name;
this.age = age;
}
}
//============输出===============
ObjectTest{x=1}
Person{x=1}
Person{name=peida, age=23}

4、firstNonNull方法
Object的firstNonNull方法可以根据传入的两个参数来返回一个非Null的参数,Guava现在推荐使用MoreObjects.firstNonNull(T first,T second)替代它。

import com.google.common.base.MoreObjects;
public class TestFilter {
public static void main(String[] args) {
//name不为空
String name="张三";
String nann= MoreObjects.firstNonNull(name, "哈哈");
System.out.println(nann);
//sex为null
String sex=null;
String sexx= MoreObjects.firstNonNull(sex, "哈哈");
System.out.println(sexx);
}
/*
*运行结果:
* 张三
* 哈哈
*/
}

在实际开发中,Objects.equal(test,"test")和MoreObjects.firstNonNull(T first,T second)在许多实际场合还是非常有帮助的。
Immutable(不可变)集合
一、概述
guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开。Collections是jdk提供的一个工具类。
Guava中不可变对象和Collections工具类的unmodifiableSet/List/Map/etc的区别:
当Collections创建的不可变集合的wrapper类改变的时候,不可变集合也会改变,而Guava的Immutable集合保证确实是不可变的。
1、JDK中实现immutable集合
在JDK中提供了Collections.unmodifiableXXX系列方法来实现不可变集合, 但是存在一些问题,下面我们先看一个具体实例:

public class ImmutableTest {
@Test
public void testJDKImmutable(){
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
//通过list创建一个不可变的unmodifiableList集合
List<String> unmodifiableList=Collections.unmodifiableList(list);
System.out.println(unmodifiableList);
//通过list添加元素
list.add("ddd");
System.out.println("往list添加一个元素:"+list);
System.out.println("通过list添加元素之后的unmodifiableList:"+unmodifiableList);
//通过unmodifiableList添加元素
unmodifiableList.add("eee");
System.out.println("往unmodifiableList添加一个元素:"+unmodifiableList);
}
}

运行结果:

通过运行结果我们可以看出:虽然unmodifiableList不可以直接添加元素,但是我的list是可以添加元素的,而list的改变也会使unmodifiableList改变。
所以说Collections.unmodifiableList实现的不是真正的不可变集合。
2、Guava的immutable集合
Guava提供了对JDK里标准集合类里的immutable版本的简单方便的实现,以及Guava自己的一些专门集合类的immutable实现。当你不希望修改一个集合类,
或者想做一个常量集合类的时候,使用immutable集合类就是一个最佳的编程实践。
注意:每个Guava immutable集合类的实现都拒绝null值。我们做过对Google内部代码的全面的调查,并且发现只有5%的情况下集合类允许null值,而95%的情况下
都拒绝null值。万一你真的需要能接受null值的集合类,你可以考虑用Collections.unmodifiableXXX。
immutable集合可以有以下几种方式来创建:
1、用copyOf方法, 譬如, ImmutableSet.copyOf(set)
2、使用of方法,譬如,ImmutableSet.of("a", "b", "c")或者ImmutableMap.of("a", 1, "b", 2)
3、使用Builder类
举例:

@Test
public void testGuavaImmutable(){ List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c"); ImmutableList<String> imlist=ImmutableList.copyOf(list);
System.out.println("imlist:"+imlist); ImmutableList<String> imOflist=ImmutableList.of("peida","jerry","harry");
System.out.println("imOflist:"+imOflist); ImmutableSortedSet<String> imSortList=ImmutableSortedSet.of("a", "b", "c", "a", "d", "b");
System.out.println("imSortList:"+imSortList); list.add("baby");
//关键看这里是否imlist也添加新元素了
System.out.println("list添加新元素之后看imlist:"+imlist); ImmutableSet<Color> imColorSet =
ImmutableSet.<Color>builder()
.add(new Color(0, 255, 255))
.add(new Color(0, 191, 255))
.build(); System.out.println("imColorSet:"+imColorSet);
}

运行结果:发现imlist并未改变。

对于排序的集合来说有例外,因为元素的顺序在构建集合的时候就被固定下来了。譬如,ImmutableSet.of("a", "b", "c", "a", "d", "b"),对于这个集合的遍历顺序来说就是"a", "b", "c", "d"。
更智能的copyOf
copyOf方法比你想象的要智能,ImmutableXXX.copyOf会在合适的情况下避免拷贝元素的操作-先忽略具体的细节,但是它的实现一般都是很“智能”的。譬如:

@Test
public void testCotyOf(){
ImmutableSet<String> imSet=ImmutableSet.of("peida","jerry","harry","lisa");
System.out.println("imSet:"+imSet); //set直接转list
ImmutableList<String> imlist=ImmutableList.copyOf(imSet);
System.out.println("imlist:"+imlist); //list直接转SortedSet
ImmutableSortedSet<String> imSortSet=ImmutableSortedSet.copyOf(imSet);
System.out.println("imSortSet:"+imSortSet); List<String> list=new ArrayList<String>();
for(int i=0;i<=10;i++){
list.add(i+"x");
}
System.out.println("list:"+list); //截取集合部分元素
ImmutableList<String> imInfolist=ImmutableList.copyOf(list.subList(2, 8));
System.out.println("imInfolist:"+imInfolist);
}

运行结果

Guava集合和不可变对应关系
| 可变集合类型 | 可变集合源:JDK or Guava? | Guava不可变集合 |
| Collection | JDK | ImmutableCollection |
| List | JDK | ImmutableList |
| Set | JDK | ImmutableSet |
| SortedSet/NavigableSet | JDK | ImmutableSortedSet |
| Map | JDK | ImmutableMap |
| SortedMap | JDK | ImmutableSortedMap |
| Multiset | Guava | ImmutableMultiset |
| SortedMultiset | Guava | ImmutableSortedMultiset |
| Multimap | Guava | ImmutableMultimap |
| ListMultimap | Guava | ImmutableListMultimap |
| SetMultimap | Guava | ImmutableSetMultimap |
| BiMap | Guava | ImmutableBiMap |
| ClassToInstanceMap | Guava | ImmutableClassToInstanceMap |
| Table | Guava | ImmutableTable |
guava之Multiset
一、概述
Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关。Multiset继承于JDK的Cllection接口,而不是Set接口。它和set最大的区别就是
它可以对相同元素做一个计数的功能,普通的 Set 就像这样 :[car, ship, bike],而 Multiset 会是这样 : [car x 2, ship x 6, bike x 3]Multiset有一个有用的功能,
就是跟踪每种对象的数量,所以你可以用来进行数字统计。每存放一个相同元素,那么该元素的count就加1。
譬如一个 List 里面有各种字符串,然后你要统计每个字符串在 List 里面出现的次数,这个用Multiset就能够快速实现。
1、举例说明

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));
}
}
}

主要看运行结果:

根据运行结果我们得到:
(1)它把把list放入HashMultiset中,就成了key还是list的属性,value就是重复数的一个计数。
(2)每添加一个相同元素,计数+1。
(3)可以添加和移除计数的值。
2、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<Multiset.Entry>。包含的Entry支持使用getElement()和getCount()
setCount(E element ,int count): 设定某一个元素的重复次数
setCount(E element,int oldCount,int newCount): 将符合原有重复个数的元素修改为新的重复次数
retainAll(Collection c) : 保留出现在给定集合参数的所有的元素
removeAll(Collectionc) : 去除出现给给定集合参数的所有的元素
3、常用的实现了Multiset 接口的类
1、HashMultiset: 元素存放于 HashMap
2、LinkedHashMultiset: 元素存放于 LinkedHashMap,即元素的排列顺序由第一次放入的顺序决定
3、TreeMultiset:元素被排序存放于TreeMap
4、EnumMultiset: 元素必须是 enum 类型
5、ImmutableMultiset: 不可修改的 Mutiset
4、Multiset与Map<E, Integer>区别
实际开发中我们也可以利用Map<E, Integer>来实现计数功能,但它和Multiset还是有很大区别的,首先Multiset也不是Map<E, Integer>类型的结构,区别如下:
1、Multiset中的元素出现的次数只能为正数,前面说了原因。如果E的出现次数为0,那么E将不出现在multiset中,是不能在elementSet()和entrySet()的视图中;
2、multiset.size()返回这个集合的大小,相当于在multiset中元素的出现的总数。如果想得到multiset中不同元素出现的总数,可以利用elementSet().size()来实现;
3、multiset.iterator()可以遍历multiset中的所有元素,所以iteration遍历的次数就等于multiset.size();
4、Multiset支持添加、删除元素,设置元素出现的次数;setCount(elem, 0)相当于移除elem的所有元素;
5、multiset.count(elem)方法中的elem如果没有出现在Multiset中,那么它的返回值永远都是0。
guava之multimap
上一篇讲到Multiset它可以对存入相同元素做一个计数的功能,那multimap呢?
一、概述
1、基本介绍和案例说明
multimap和MultiSet的继承结果很相似,只不过在上层的接口是Multimap不是Multiset。
Multimap的特点其实就是可以包含有几个重复Key的value,你可以put进入多个不同value但是相同的key,但是又不是让后面覆盖前面的内容。
它的业务场景:当你需要构造像Map<K, List<V>>或者Map<K, Set<V>>这样比较复杂的集合类型的数据结构,来做相应的业务逻辑处理。那Multimap在合适不过。
举例

@Test
public void testMultimap(){
HashMultimap<Integer, Integer> map = HashMultimap.create();
map.put(1, 2);
map.put(1, 3);
map.put(1, 2);
map.put(2, 3);
map.put(4, 2);
map.put(4, 3);
map.put(4, 2);
map.put(4, 3);
System.out.println(map.toString());
}
}
/*输出结果:
*{1=[2, 3], 2=[3], 4=[2, 3]}
*/

其实它会把相同key和value的值给覆盖起来,但是相同的key又可以保留不同的value。因为它的entry的实现是一个set,set会对相同的Entry<K,V>进行去重,所以会有这种情况。
2、实际开发场景及常用方法
(1)根据业务需要对下面的list数据根据name字段来进行分组:

[
{
"date":"2018-01-31",
"name":"wuzhong",
"socre":0.8
},
{
"date":"2018-01-30",
"name":"wuzhong",
"socre":0.9
},
{
"date":"2018-01-31",
"name":"wuzhong2",
"socre":0.8
}
]

传统做法:

//Item就是封装的对象
Map<String,List<Item>> map = new HashMap<>();
for (Item item : list){
List<Item> tmp = map.get(item.getName());
if (null == tmp){
tmp = new ArrayList<>();
map.put(item.getName(),tmp);
}
tmp.add(item);
}

很简单, 但是代码量有点多,特别是需要判断List为null并初始化。
再用guava实现上述的功能:
Multimap<String,Item> multiMap = ArrayListMultimap.create();
for (Item item : list){
multiMap.put(item.getName(),item);
}
代码量直接减少了一半,这就是实际开发中它发挥的作用。
(2)再举一例子了解常用方法:

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]
*/

4、Multimap的实现类
Multimap提供了丰富的实现,所以你可以用它来替代程序里的Map<K, Collection<V>>,具体的实现如下:
Implementation Keys 的行为类似 Values的行为类似
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap LinkedHashMap* LinkedList*
LinkedHashMultimap LinkedHashMap LinkedHashSet
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
ImmutableSetMultimap ImmutableMap ImmutableSet
以上这些实现,除了immutable的实现都支持null的键和值。
1、LinkedListMultimap.entries()能维持迭代时的顺序。
2、LinkedHashMultimap维持插入的顺序,以及键的插入顺序。
guava之Bimap
bimap的作用很清晰:它是一个一一映射,可以通过key得到value,也可以通过value得到key。
一、概述
1、bimap和普通HashMap区别
(1)在Java集合类库中的Map,它的特点是存放的键(Key)是唯一的,而值(Value)可以不唯一,而
bimap要求key和value都唯一,如果key不唯一则覆盖key,如果value不唯一则直接报错。
2、案例展示

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值 --小小
*/

如果value值重复,则运行直接报错如下:

biMap.put(6,"小小");
/**后台直接报错
* Exception in thread "main" java.lang.IllegalArgumentException: value already present: 小小
* at com.google.common.collect.HashBiMap.put(HashBiMap.java:285)
* at com.google.common.collect.HashBiMap.put(HashBiMap.java:260)
* at com.jincou.stream.study.bimapTest.main(bimapTest.java:40)
*/

如果你想value也发生覆盖key值,那么可以:

// inverse方法会返回一个反转的BiMap,但是注意这个反转的map不是新的map对象,它实现了一种视图关联,这样你对于反转后的map的所有操作都会影响原先的map对象。
biMap.forcePut(6,"小小");
int key6= biMap.inverse().get("小小");
System.out.println("小小key值 --"+key6);
/**后台输出(已经把:biMap.put(4,"小小"覆盖)
*
* 小小key值 --6
*/

3、Bimap实现类
BiMap的常用实现有:
1、HashBiMap: key 集合与 value 集合都有 HashMap 实现
2、EnumBiMap: key 与 value 都必须是 enum 类型
3、ImmutableBiMap: 不可修改的 BiMap
guava字符串工具
在java开发过程中对字符串的处理是非常频繁的,google的guava工具对字符串的一些处理进行优化,使我们开发过程中让自己的代码看去更加美观,清爽。
一、Joiner
根据给定的分隔符把字符串连接到一起。MapJoiner 执行相同的操作,但是针对 Map 的 key 和 value。
分析源码可知:该类构造方法被private修身,无法直接通过new实现,通过调用on传如分隔符来得到实例。
案例

public class JoinerTest {
public static void main(String args[]){
//1、将list字符串集合,以,形式转为字符串
List<String> list =new ArrayList<String>();
list.add("xx");
list.add("zz");
list.add("dd");
//Joiner.on(",")获得Joiner实例对象
Joiner joiner = Joiner.on(",");
//joiner.join(list)传入操作的集合,并转成字符串格式
System.out.println(joiner.join(list));
//输出结果:xx,zz,dd
//2、将Iterator<T>列表,转为字符串
Iterator<String> it=list.iterator();
String str=Joiner.on("|").join(it);
System.out.println(str);
//输出结果:xx|zz|dd
//3、连接多个字符串
String str1=Joiner.on(",").join("小小","爸爸","妈妈","爷爷","奶奶");
System.out.println(str1);
//输出:小小,爸爸,妈妈,爷爷,奶奶
//4、连接字符串与列表
StringBuilder builder=new StringBuilder("小小最乖");
//返回StringBuilder类型
StringBuilder str2=Joiner.on(",").appendTo(builder,list);
System.out.println(str2);
//输出:小小最乖xx,zz,dd
//5、跳过null值连接
list.add(null);
list.add("小小");
//skipNulls()代表去除null
String str3=Joiner.on(",").skipNulls().join(list);
System.out.println(str3);
//输出:xx,zz,dd,小小
//6、替换null值进行连接
String str4=Joiner.on(",").useForNull("空").join(list);
System.out.println(str4);
//输出:xx,zz,dd,空,小小
//7、Map的键值对打印出来
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("=");
System.out.println(mapJoiner.join(map));
//输出:key1=value1,key2=value2,key3=value3
//8、一步将字符串转为List<Long>集合(前面先转为list<String>,后面用java8特性将List<String>转为List<Long>)
List<Long> list=Splitter.on("#").splitToList("111#222#333").stream().mapToLong(str->Long.parseLong(str)).boxed().distinct().collect(Collectors.toList());
} }

Joiner在实际开发中,用处还是蛮大的。
二、Splitter
主要功能是拆分字符串为集合 Map等。 通过分析源码可知,该工具类是通过on函数传入拆分字符得到实例。
案例:

public class SplitterTest {
public static void main(String args[]){
//1、拆分字符串为List集合
String str="小小,妈妈,爸爸,爷爷,奶奶";
Splitter splitter =Splitter.on(",");
List<String> list=splitter.splitToList(str);
System.out.println(list);
//输出:[小小, 妈妈, 爸爸, 爷爷, 奶奶]
//2、忽略空字符
String str1="a,b,c,d,,f,g";
//omitEmptyStrings()代表去除空字符串
List<String> list1=Splitter.on(",").omitEmptyStrings().splitToList(str1);
System.out.println(list1);
//输出:[a, b, c, d, f, g]
//3、忽略空字符且去除字符串前后空格
String str2="a,b,c,d,,f, g ";
List<String> list2=Splitter.on(",").omitEmptyStrings().trimResults().splitToList(str2);
System.out.println(list2);
//输出:[a, b, c, d, f, g]
}
}

三、Strings
案例

public class StringsTest {
public static void main(String args[]){
//1、补右全(Strings.padEnd方法)
String a="12345";
String b=Strings.padEnd(a, 10, 'x');
System.out.println(b);
//输出:12345xxxxx
//2、补左全(Strings.padStart)
String c=Strings.padStart(a, 10, 'x');
System.out.println(c);
//输出:xxxxx12345
//3、校验空值和null
String d="";
String f=null;
boolean e=Strings.isNullOrEmpty(d);
boolean h=Strings.isNullOrEmpty(f);
System.out.println(e);
System.out.println(h);
//输出:true,true
//4、如果为null 转为""
String m=null;
String n=Strings.nullToEmpty(m);
System.out.println(n);
//输出:
//5、如果为"" 转为null
String j="";
String k=Strings.emptyToNull(j);
System.out.println(k);
//输出:null
//6、重复字符串(Strings.repeat)
String o="123";
String p=Strings.repeat(o, 3);
System.out.println(p);
//输出:123123123
//7、获取a,b左公共部分字符串(左边第一个公共部分)
String r="abcdsfsfs";
String s="accdc3sfsd";
String t=Strings.commonPrefix(r, s);
System.out.println(t);
//输出:a
//8、获取a,b右公共部分字符串
String w="faaxyz";
String x="fwefxyz";
String z=Strings.commonSuffix(w, x);
System.out.println(z);
//输出:xyz
}
}
guava之Lists、Maps
谷歌提供了guava包里面有很多的工具类,Lists和Maps集合工具,集合操作做了些优化提升。
1、概述
1、静态工厂方法
(1)Guava提供了能够推断范型的静态工厂方法
List<Person> list = Lists.newArrayList();
Map<KeyType, Person> map = Maps.newLinkedHashMap();
(2) 用工厂方法模式,我们可以方便地在初始化时就指定起始元素。
Set<Type> copySet = Sets.newHashSet(elements);
List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
(3) 通过为工厂方法命名,我们可以提高集合初始化大小的可读性.
List<Type> exactly100 = Lists.newArrayListWithCapacity(100);
List<Type> approx100 = Lists.newArrayListWithExpectedSize(100);
Set<Type> approx100Set = Sets.newHashSetWithExpectedSize(100);
二、Lists案例

public class ListsTest {
public static void main(String args[]){
List<String> list1 = Lists.newArrayList();
for (int i = 0; i < 10; i++) {
list1.add(i + "");
}
System.out.println("list1: " + list1);
//输出:list1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//2、传入多参数
List<String> list2 = Lists.newArrayList("1", "2", "3");
System.out.println("list2: " + list2);
//输出:list2: [1, 2, 3]
//3、传入数组
List<String> list3 = Lists.newArrayList(new String[]{"22", "22"});
System.out.println("list3: " + list3);
//输出:list3: [22, 22]
//4、传入集合
List<String> list4 = Lists.newArrayList(list1);
System.out.println("list4: " + list4);
//输出:list4: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//5、使用条件:你确定你的容器会装多少个,不确定就用一般形式的
//说明:这个容器超过10个还是会自动扩容的。不用担心容量不够用。默认是分配一个容量为10的数组,不够将扩容
//整个来说的优点有:节约内存,节约时间,节约性能。代码质量提高。
List<String> list = Lists.newArrayListWithExpectedSize(10);
//这个方法就是直接返回一个10的数组。
List<String> list_ = Lists.newArrayListWithCapacity(10);
}
}

三、Maps案例

public class MapsTest {
public static void main(String[] args) {
//1、Maps.newHashMap()获得HashMap();
Map<Integer, Integer> map0 = Maps.newHashMap();
for (int i = 0; i < 10; i++) {
map0.put(i, i);
}
System.out.println("map0:" + map0);
//输出:map0:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}
//2、传入map0参数构建map
Map<Integer, Integer> map1 = Maps.newHashMap(map0);
map1.put(10, 10);
System.out.println("map1:" + map1);
//输出:map1:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9, 10=10}
//3、使用条件:你确定你的容器会装多少个,不确定就用一般形式的
//说明:这个容器超过3个还是会自动扩容的。不用担心容量不够用。默认是分配一个容量为16的数组,不够将扩容
Map<Integer, Integer> map2 = Maps.newHashMapWithExpectedSize(3);
map2.put(1, 1);
map2.put(2, 2);
map2.put(3, 3);
System.out.println("map2:" + map2);
//输出:map2:{1=1, 2=2, 3=3}
//4、LinkedHashMap<K, V> 有序map
//Map<Integer,Integer> map3 = Maps.newLinkedHashMap();
//Map<Integer,Integer> map3 = Maps.newLinkedHashMapWithExpectedSize(11);
Map<Integer, Integer> map3 = Maps.newLinkedHashMap(map1);
map3.put(11, 11);
System.out.println("map3:" + map3);
//输出:map3:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9, 10=10, 11=11}
outMapKeyValue(map3);
}
/**
* 遍历Map的四种方法
*/
private static void outMapKeyValue(Map<Integer, Integer> map3) {
//1.通过Map.entrySet遍历key和value
for (Map.Entry<Integer, Integer> integerEntry : map3.entrySet()) {
System.out.println("key:" + integerEntry.getKey() + " value:" + integerEntry.getValue());
}
//2.通过Map.entrySet使用iterator遍历key和value-----不推荐,直接用上面的for each循环代替此方法
Iterator<Map.Entry<Integer, Integer>> it = map3.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, Integer> entry = it.next();
System.out.println("key:" + entry.getKey() + " value:" + entry.getValue());
}
//3.通过Map.keySet遍历key;根据key得到value
for (Integer integer : map3.keySet()) {
System.out.println("key:" + integer + " value:" + map3.get(integer));
}
//4.通过Map.values()遍历所有的value,但不能遍历key
for (Integer integer : map3.values()) {
System.out.println("value:" + integer);
}
}
}
java代码之美(2)的更多相关文章
- java代码之美(14)---Java8 函数式接口
Java8 函数式接口 之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加 ...
- java代码之美(15)---Java8 Function、Consumer、Supplier
Java8 Function.Consumer.Supplier 有关JDK8新特性之前写了三篇博客: 1.java代码之美(1)---Java8 Lambda 2.java代码之美(2)---Jav ...
- java代码之美(11)---java代码的优化
java代码的优化 随着自己做开发时间的增长,越来越理解雷布斯说的: 敲代码要像写诗一样美.也能理解有一次面试官问我你对代码有洁癖吗? 一段好的代码会让人看就像诗一样,也像一个干净房间会让人看去很舒服 ...
- java代码之美(3)---guava 复写Object常用方法
guava 复写Object常用方法 Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,这个库提供用于集合,缓存,支持原语,并发性,常见注解,字符串处理,I/O和验证的实用方 ...
- java代码之美(12)---CollectionUtils工具类
java代码之美(12)---CollectionUtils工具类 这篇讲的CollectionUtils工具类是在apache下的, 而不是springframework下的CollectionUt ...
- java代码之美(10)---Java8 Map中的computeIfAbsent方法
Map中的computeIfAbsent方法 Map接口的实现类如HashMap,ConcurrentHashMap,HashTable等继承了此方法,通过此方法可以在特定需求下,让你的代码更加简洁. ...
- java代码之美(8)---guava字符串工具
guava字符串工具 在java开发过程中对字符串的处理是非常频繁的,google的guava工具对字符串的一些处理进行优化,使我们开发过程中让自己的代码看去更加美观,清爽. 一.Joiner 根据给 ...
- java代码之美(4)---guava之Immutable(不可变)集合
Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...
- java代码之美(2)---Java8 Stream
Stream 第一次看到Stream表达式就深深把我吸引,用它可以使你的代码更加整洁而且对集合的操作效率也会大大提高,如果你还没有用到java8的Stream特性,那就说明你确实out啦. 一.概述 ...
- java代码之美(1)---Lambda
Lambda 一.概述 1.什么是Lambda表达式 Lambda 表达式是一种匿名函数,简单地说,它是没有声明的方法,也即没有访问修饰符.返回值声明和名字. 它可以写出更简洁.更灵活的代码.作为一种 ...
随机推荐
- 灵活轻巧的java接口自动化测试实战
前言 无论是自动化测试还是自动化部署,撸码肯定少不了,所以下面的基于java语言的接口自动化测试,要想在业务上实现接口自动化,前提是要有一定的java基础. 如果没有java基础,也没关系.这里小编也 ...
- 干货分享 | PCB测试点的用途
PCB测试点长什么样子?请看下图: 如果你曾经用过NOKIA手机,每次你打开后盖换电池的时候,每次看到的那两排圆形的点--就是PCB测试点,or you can call it Test Po ...
- 推荐手绘工具神器Excalidraw素描草图风格白板,支持AI-开源免费
推荐手绘工具神器Excalidraw素描草图风格白板,支持AI-开源免费 原创 IT软件部落 IT软件部落 Excalidraw 一个开源的虚拟手绘风格的白板,是一个很好的素描工具.它真的很容易使用, ...
- Lucene 源代码剖析-2 Lucene是什么
转载自 http://download.csdn.net/source/858994 源地址下是 Word 文档,这里转换成HTML 格式 1 Lucene是什么 Apache L ...
- 使用 fiddler 进行抓包处理
1.概述 fiddler是一个抓包工具,有时候方便我们在访问网页上,看看网页的参数和返回结果.其中很重要的一条是,可以查看网页的响应速度,在对于调优方面提供一些依据. 2.软件安装 我们可以通过360 ...
- element-ui季度选择组件
1.基于elementui开发的季度选择组件 2.调用 <el-quarter-picker v-model="start_time" :size="size&qu ...
- Mock.js 笔记
1.介绍 官方文档,Mock.js用来生成随机数据,拦截 Ajax 请求 支持的数据类型丰富,包括文本.数字.布尔值.日期.邮箱.链接.图片.颜色等 功能灵活,生成随机数据 和 拦截 Ajax 请求 ...
- django admin 后台管理 新手学习步骤记录 (2)
学习使用django admin后台管理. 参考.Django基础之Admin后台数据管理_django admin_马航行的博客-CSDN博客
- Navicat连接Oracle数据库报错:oracle library is not loaded解决方法
连接Oracle时提示"oracle library is not loaded". 去Oracle官网下载Oracle Instant Client Downloads. htt ...
- liunx安装docker,portainer,mysql,rabbitMQ,nacos
由于公司框架迭代了,故此写个随笔,记录一下,方便日后回顾 1.准备 阿里云服务器(liunx CentOS 7.6) 2.前置工作 (1)查看系统版本 lsb_release -a (2)查看系统以及 ...