Guava中的常見集合操作用法


      本文主要介紹Guava中幾種處理字符串Map方法,包括Joiner(連接)FluentIterable(過濾、轉換集合)和Splitter(分割)。本文基於Java 8進行測試,Guava 版本為 

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>29.0-jre</version>
</dependency>

 Joiner

      我們來看看下面經常遇見的一個案例:定義包含如下元素的一個列表,請按照英文逗號分割,並過濾掉值null元素  

"a", null, "b", "g", "8", "9"

    用JDK中的方法實現方案如下: 

 @Test public void joinerListByJdkTest() { List<String> lists = Lists.newArrayList("a", null, "b", "g", "8", "9"); StringBuilder sb = new StringBuilder(); for (Object item : lists) { if (item != null) { sb.append(item) .append(DELIMITER); } } LOGGER.info(sb.substring(0, sb.length() - DELIMITER.length())); }

       執行結果:a,b,g,8,9。 

      是不是很簡單,但是繁瑣?例如for循環執行結束之后必須修正字符串末尾分隔符:sb.substring(0, sb.length() - DELIMITER.length());Guava版本呢? 

 @Test public void joinerListByGuavaTest() { List<String> lists = Lists.newArrayList("a", null, "b", "g", "8", "9"); String result = Joiner.on(DELIMITER).skipNulls().join(lists); LOGGER.info(result); }

   我們不再考慮更多的細節,並且很有語義的告訴代碼的閱讀者用什么分隔符分隔,需要過濾null值再join 

      關於Map對象的連接,Guava提供withKeyValueSeparator用於指定鍵值對直接的分隔符 

    /** * joiner withKeyValueSeparator(String keyValueSeparator) map連接器,keyValueSeparator為key和value之間的分隔符 * <p> * 結果: * 1:哈哈,2:壓壓 */ @Test public void withMapTest() { Map<Integer, String> maps = Maps.newHashMap(); maps.put(1, "哈哈"); maps.put(2, "壓壓"); String result = Joiner.on(DELIMITER).withKeyValueSeparator(":").join(maps); System.out.println(result); }

  

FluentIterable

  轉換(transform)集合類型,transform接收Function接口,一般在方法中采用new接口實現回調方法apply的方式。

      FluentIterable guava集合類中常用的一個類,主要用於過濾、轉換集合中的數據;它是一個抽象類,實現了Iterable接口,大多數方法都返回FluentIterable對象,這也是guava的思想之一。下面主要針對filter transform方法進行演示。filter方法要接收Predicate接口,transform接收Function接口。

      Filter的應用實例:

    /** * 過濾出年齡大於20歲的學生 * <p> * 這里有一個潛在的坑,在高版本(21.0++)的guava中Predicate接口繼承了java 8中的java.util.function.Predicate * * @param students */
    public static void filterStudents(List<Student> students) { FluentIterable<Student> filter = FluentIterable.from(students).filter( new Predicate<Student>() { @Override public boolean apply(Student student) { return Integer.valueOf(student.getAge()) > 20; } }); for (Student student : filter) { System.out.println(student); } }

      transform三種類型的應用:

    private void myTest(List<Student> students) { FluentIterable<String> transform = (FluentIterable<String>) FluentIterable.from(students).transform( new Function<Student, String>() { @Override public String apply(Student user) { // 以分隔符#分隔姓名和年齡
                        return Joiner.on("#").join(user.getName(), user.getAge()); } }); for (String user : transform) { System.out.println(user); } } /** * 返回格式化后的列表 */
    private void myTestList(List<Student> students) { // 直接返回 List 類型對象
        List<String> transform = FluentIterable.from(students).transform( new Function<Student, String>() { @Override public String apply(Student user) { return Joiner.on("=").join(user.getName(), user.getAge()); } }).toList(); System.out.println(transform); } /** * 定制特殊格式,並返回合並后的字符串 * 這里有一個潛在的坑,在版本 18.0才可以使用 .join(Joiner.on("、")) * @param students */
    private void givenFormater(List<Student> students) { String result = FluentIterable.from(students).transform(new Function<Student, String>() { @Override public String apply(Student user) { // 通過特殊格式定制字符串
                return user.getName() + "(" + user.getAge() + ")"; } // 指定各個字符串之間的分隔符
        }).join(Joiner.on("、")); System.out.println(result); } @Test public void guavaStudy() { List<Student> students = new ArrayList<>(); Student student = new Student(); student.setName("Lucy"); student.setAge("19"); students.add(student); students.add(new Student("Wiener", "32", "河南商丘")); students.add(new Student("East7", "21")); myTest(students); LOGGER.info("----- givenFormater ------"); givenFormater(students); myTestList(students); LOGGER.info("----- filterStudents ------"); filterStudents(students); }

      函數givenFormater比較特殊,其執行結果如下

Lucy(19)、Wiener(32)、East7(21)

      可以看到,其定制結果集格式的功能非常強悍。

Splitter

      Splitter可以對字符串進行分割,其分割的方式有兩種——按字符/字符串分割和按正則進行分割,下面分析按字符分隔

   /** * on 按照指定分隔符分隔字符串 * 結果:[ 河南商丘, 767, 32, , 哈哈 ] */ @Test public void splitterListTest() { String test = "  河南商丘,767,32,,哈哈 "; List<String> lists = Splitter.on(DELIMITER).splitToList(test); System.out.println(lists); } /** * trimResults 拆分並且去除元素前后空格 * <p> * 結果:[河南商丘, 767, 32, , 哈哈] */ @Test public void trimResultListTest() { String test = "  河南商丘,767,32,,哈哈 "; List<String> lists = Splitter.on(DELIMITER).trimResults().splitToList(test); System.out.println(lists); } /** * omitEmptyStrings 去除拆分后的、空的字符串 * <p> * 結果:[河南商丘, 767, 32, 哈哈] */ @Test public void omitEmptyStringsTest() { String test = "  河南商丘,767,32,,哈哈 "; List<String> lists = Splitter.on(DELIMITER).omitEmptyStrings().trimResults().splitToList(test); System.out.println(lists); }

Reference

https://www.cnblogs.com/whitewolf/p/4214749.html

 

<


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM