`

Guava: Joiner & Splitter

阅读更多

1. Joiner

    Comparasion between traditional approach and Guava approach:

    @Test
    public void buildStringTest() {
	List<String> data = Lists.newArrayList("A", "B", "C", null, "D", "E",
		"F");
	String str = buildString(data, ",");
	assertEquals("A,B,C,D,E,F", str);
    }

    public String buildString(List<String> data, String delimeter) {
	StringBuilder sb = new StringBuilder();
	for (String s : data) {
	    if (null != s) {
		sb.append(s).append(delimeter);
	    }
	}
	sb.setLength(sb.length() - delimeter.length());
	return sb.toString();
    }
    @Test
    public void joinTest() throws IOException {
	List<String> data = Lists.newArrayList("A", "B", "C", null, "D", "E",
		"F");
	String str = Joiner.on(",").skipNulls().join(data);
	assertEquals("A,B,C,D,E,F", str);
    } 

   Note the need to remove the last delimeter that was appended to the very end of the string.

   Not very complicated, but it's still some boilerplate code that can be more easily handled by using the Joiner class.

 

2. Joiner usage

   1> Simple Usage

    @Test
    public void joinTest() throws IOException {
	List<String> data = Lists.newArrayList("A", "B", "C", null, "D", "E",
		"F");
	String str = Joiner.on(",").skipNulls().join(data);
	logger.info(str);
	assertEquals("A,B,C,D,E,F", str);

	str = Joiner.on("|").useForNull("NULL").join(data);
	logger.info(str);
	assertEquals("A|B|C|NULL|D|E|F", str);

	StringBuilder sb = new StringBuilder("X|M|U|");
	Joiner.on("|").skipNulls().appendTo(sb, data);
	logger.info(sb.toString());
	assertEquals("X|M|U|A|B|C|D|E|F", sb.toString());

	FileWriter fw = new FileWriter(new File("src/test/resources/test.csv"));
	Joiner.on(",").useForNull(" ").appendTo(fw, data);
	fw.close();
    }
public <A extends Appendable> A appendTo(A appendable, Iterable<?> parts);
appendTo can be used for any class that implements Appendable interface.

    2> Attention:

        1) Joiner instances are always immutable. The joiner configuration methods will always return a new Joiner, which you must use to get the desired semantics.

             This makes any Joiner thread safe, and usable as a static final constant.

    @Test
    public void joinTest() throws IOException {
	List<String> data = Lists.newArrayList("A", "B", "C", null, "D", "E",
		"F");
	Joiner joiner = Joiner.on(",");
	joiner.skipNulls();
	String str = joiner.join(data);
	logger.info(str);
    }
    // NullPointerException will be thrown.

    @Test
    public void joinTest() throws IOException {
	List<String> data = Lists.newArrayList("A", "B", "C", null, "D", "E",
		"F");
	Joiner joiner = Joiner.on(",");
	joiner = joiner.skipNulls();
	String str = joiner.join(data);
	logger.info(str);
    }
    // A,B,C,D,E,F
  public static Joiner on(String separator) {
    return new Joiner(separator);
  }

  public Joiner useForNull(final String nullText) {
    checkNotNull(nullText);
    return new Joiner(this) {...}
  }

  public Joiner skipNulls() {
    return new Joiner(this) {...}
  }

        2) The returned Joiner is slightly different from traditional Joiner.

    @Test
    public void joinTest() throws IOException {
	List<String> data = Lists.newArrayList("A", "B", "C", null, "D", "E",
		"F");
	Joiner joiner = Joiner.on(",");
	joiner = joiner.skipNulls().useForNull("NULL");
	String str = joiner.join(data);
	logger.info(str);
    }

    // UnsupportedOperationException will be thrown indicates that "already specified skipNulls"

          How to achieve that?

  public Joiner skipNulls() {
    return new Joiner(this) {
      @Override public Joiner useForNull(String nullText) {
        throw new UnsupportedOperationException("already specified skipNulls");
      }
    };
  }

  public Joiner useForNull(final String nullText) {
    return new Joiner(this) {
      @Override public Joiner useForNull(String nullText) {
        throw new UnsupportedOperationException("already specified useForNull");
      }

      @Override public Joiner skipNulls() {
        throw new UnsupportedOperationException("already specified useForNull");
      }
    };
  }

 

3. MapJoiner usage

    @Test
    public void joinTest() throws IOException {
	Map<String, String> data = Maps.newHashMap();
	data.put("Name", "Davy");
	data.put("Gender", "Male");
	data.put("Age", "24");
	Joiner joiner = Joiner.on(",");
	MapJoiner mapJoiner = joiner.withKeyValueSeparator("=");
	String str = mapJoiner.join(data);
	logger.info(str);
	assertEquals("Name=Davy,Age=24,Gender=Male", str);
        // Use "," as separator for entry, and  "=" as separator for key and value
    }

    Source code: 

    public <A extends Appendable> A appendTo(A appendable, Iterator<? extends Entry<?, ?>> parts)
        throws IOException {
      checkNotNull(appendable);
      if (parts.hasNext()) {
        Entry<?, ?> entry = parts.next();
        appendable.append(joiner.toString(entry.getKey()));
        appendable.append(keyValueSeparator);
        appendable.append(joiner.toString(entry.getValue()));
        while (parts.hasNext()) {
          appendable.append(joiner.separator);
          Entry<?, ?> e = parts.next();
          appendable.append(joiner.toString(e.getKey()));
          appendable.append(keyValueSeparator);
          appendable.append(joiner.toString(e.getValue()));
        }
      }
      return appendable;
    }

 

2. Splitter: 

    1> Comparasion between traditional approach and Guava approach:

    @Test
    public void splitTest() {
	String str = "Monday,Tuesday,,Thursday,Friday,,";
	String[] strs = str.split(",");
	String[] exp = new String[] { "Monday", "Tuesday", "", "Thursday",
		"Friday" };
	assertArrayEquals(exp, strs);
    }
    @Test
    public void splitTest() {
	String str = "Monday,Tuesday,,Thursday,Friday,,";
	List<String> strs = Splitter.on(',').splitToList(str);
	List<String> exp = Lists.newArrayList("Monday", "Tuesday", "",
		"Thursday", "Friday", "", "");
	assertEquals(exp, strs);
    }
    @Test
    public void splitTest() {
	String str = "Monday,Tuesday,,Thursday,Friday,,";
	List<String> strs = Splitter.on(',').omitEmptyStrings()
		.splitToList(str);
	List<String> exp = Lists.newArrayList("Monday", "Tuesday", "Thursday",
		"Friday");
	assertEquals(exp, strs);
    }
    @Test
    public void splitTest() {
	String str = "Monday, Tuesday, , Thursday, Friday, , ";
	List<String> strs = Splitter.on(',').omitEmptyStrings().trimResults()
		.splitToList(str);
	List<String> exp = Lists.newArrayList("Monday", "Tuesday", "Thursday",
		"Friday");
	assertEquals(exp, strs);
    }
    @Test
    public void splitTest() {
	String str = "Monday, Tuesday, , Thursday, Friday, , ";
	List<String> strs = Splitter.on(',').trimResults().splitToList(str);
	List<String> exp = Lists.newArrayList("Monday", "Tuesday", "",
		"Thursday", "Friday", "", "");
	assertEquals(exp, strs);
    }

    We can see that using Guava Splitter, the result is more reasonable and comprehensive.

    2> MapSplitter

    @Test
    public void splitTest() {
	String str = "Name=Davy;Age=24;Gender=Male";
	Map<String, String> expectedMap = Maps.newLinkedHashMap();
	expectedMap.put("Name", "Davy");
	expectedMap.put("Age", "24");
	expectedMap.put("Gender", "Male");
	Map<String, String> generatedMap = Splitter.on(';')
		.withKeyValueSeparator("=").split(str);
	assertEquals(expectedMap, generatedMap);
    }
    public Map<String, String> split(CharSequence sequence) {
      Map<String, String> map = new LinkedHashMap<String, String>();
      for (String entry : outerSplitter.split(sequence)) {
        Iterator<String> entryFields = entrySplitter.splittingIterator(entry);

        checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
        String key = entryFields.next();
        checkArgument(!map.containsKey(key), "Duplicate key [%s] found.", key);

        checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
        String value = entryFields.next();
        map.put(key, value);

        checkArgument(!entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
      }
      return Collections.unmodifiableMap(map);
    }
  }

    We can see from the source code that we are using ";" for outterSplitter and "=" for entrySplitter.

    @Test
    public void splitTest() {
	String str = "Name = Davy; Age = 24; Gender = Male";
	Map<String, String> expectedMap = Maps.newLinkedHashMap();
	expectedMap.put("Name", "Davy");
	expectedMap.put("Age", "24");
	expectedMap.put("Gender", "Male");
	Map<String, String> generatedMap = Splitter.on(';').trimResults()
		.withKeyValueSeparator(Splitter.on("=").trimResults())
		.split(str);
	assertEquals(expectedMap, generatedMap);
    }

    In the example above, we are using ";" as outterSplitter and thus trimResults to "Name = Davy", "Age = 24", "Gender = Male"

    And we are using "=" as entrySplitter and thus trimResults to "Name", "Davy"...

 

3. Preconditions

    The Preconditions class is a collection of static methods used to verify the state of our code.

    public void setName(String name) {
	if (null == name) {
	    throw new IllegalArgumentException("name cannot be null");
	}
    }
    public void setName(String name) {
        Preconditions.checkNotNull(name);
    }
    public void setName(String name) {
        Preconditions.checkArgument(null != name && !"".equals(name.trim()));
    }
    @Test
    public void conditionsTest() {
	String[] data = new String[] { "A", "B", "C", "D" };
	getValue(data, 4);
    }
    private void getValue(String[] data, int i) {
        Preconditions.checkElementIndex(data.length, i);
    }

 

Reference Links:

1> "Getting Started with Google Guava" -Bill Bejeck

分享到:
评论

相关推荐

    google开源项目guava.jar包

    另外,Splitter和Joiner类则帮助我们更灵活地处理字符串分割与连接。 I/O操作在Guava中通过Files、ByteStreams、CharStreams等类得到优化,它们提供了更高效、简洁的接口来读写文件、处理流。例如,Files类允许直接...

    Guava:Guava Google模块

    在字符串处理方面,Guava提供了Joiner和Splitter,使得拼接和分割字符串变得更加方便。例如,Joiner可以用来方便地连接列表或数组,而Splitter则可以根据特定的分隔符来拆分字符串。 Guava的I/O工具也非常强大,...

    Guava 工程项目包 有实例

    - **Joiner 和 Splitter**:Guava 提供了 Joiner 和 Splitter 类,用于高效地连接字符串和分割字符串,比使用 "+" 或 String.split() 更加灵活和高效。 - **预格式化字符串**:Preconditions 类提供了一些静态方法...

    Guava:使用 Google Guava 框架

    Guava 提供了非常强大的字符串处理工具,如 Joiner 和 Splitter,使得字符串连接和分隔操作变得简单易用。此外,它还提供了预定义的格式化器和 Predicates,帮助开发者更方便地处理字符串。 **6. I/O 工具** Guava...

    Getting Started with Google Guava code

    5. **字符串处理**:Guava 提供了各种字符串工具,如 Joiner、Splitter 和 CharMatcher,可以更方便地进行字符串操作。 6. **I/O 操作**:Guava 提供了 Files、ByteStreams 和 CharStreams 等类,使得文件读写和流...

    java&guava讲义.pptx

    * Guava 对 String 的支持:提供了多种字符串操作,例如 Joiner、Splitter 等。 * Immutable 对象:Guava 中的许多对象都是不可变的,例如 String、BigDecimal 等。 * 线程安全:Guava 的大多数类都是线程安全的。 ...

    guava学习笔记

    本学习笔记将重点介绍Guava中的几个核心工具类:Joiner、Splitter、Preconditions。 1. Joiner类与Splitter类 Joiner类的主要功能是将集合中的元素拼接成一个字符串。通过指定分隔符,可以灵活地将集合或Map中的...

    guava多个版本jar包

    此外,还有并发工具,如CountDownLatch、Future和ListenableFuture,以及强大的字符串处理类,如Joiner和Splitter。它还包含了Guava的缓存机制,允许高效地存储和检索数据。 2. guava-18.0.jar:这是一个较大的升级...

    guava-jdk5

    5. **字符串处理**:Guava提供了一系列的字符串处理工具,如Joiner、Splitter、CharMatcher等,使字符串操作更加方便和高效。例如,Joiner可以方便地将多个字符串连接成一个,Splitter可以按特定规则分割字符串。 6...

    不加密Google Guava视频教程.txt

    ├─Google Guava 第01讲-Joiner详细介绍以及和Java8Collector对比.wmv ├─Google Guava 第02讲-Guava Splitter详细讲解以及实战练习.wmv ├─Google Guava 第03讲-Preconditions&Objects;&assert;讲解.wmv ├─...

    Guava入门指南培训PPT

    - **面向对象风格**:相较于Apache Commons Lang中的静态方法,Guava通过创建`Splitter`对象来进行字符串分割,更加符合面向对象的设计原则。 - **性能对比**: - Apache Commons Lang:平均耗时约406毫秒。 - ...

    guava-18.0资料

    5. **字符串处理**:Guava提供了Strings类,包含大量用于字符串操作的方法,如Joiner和Splitter,简化了字符串连接和分割的操作。 6. **I/O操作**:Guava的Files类提供了对文件系统的低级别访问,而CharStreams和...

    guava-API文档

    4. 字符串处理:Guava包含了一些方便的字符串处理方法,如Joiner和Splitter,它们可以更方便地进行字符串的连接和分割操作。此外,CharMatcher类可以帮助进行字符过滤,Strings类则提供了各种字符串操作的静态方法。...

    guava源码src

    4. **字符串处理**:Guava提供了丰富的字符串工具,如Joiner、Splitter、CharMatcher等,可以方便地进行字符串连接、分割和过滤。这些工具在处理复杂字符串操作时,比Java内置的String类更加高效和灵活。 5. **函数...

    Getting Started with Google Guava.pdf

    此外,Guava还引入了`Joiner`和`Splitter`两个类,它们可以轻松地将字符串进行拼接或分割。 ##### 4. 缓存机制 Guava的缓存实现`CacheBuilder`提供了创建高性能内存缓存的功能,这在需要频繁访问的数据上特别有用...

    guava23.0,用于安卓软件开发

    此外,它还包含了一些便捷的集合操作方法,如Joiner和Splitter用于字符串处理,以及Immutable集合类,确保集合在创建后无法被修改,这对于线程安全和防止意外修改非常有用。 2. **缓存机制**:Guava的Cache模块允许...

    Guava使用培训教程

    通过上述介绍可以看出,Guava库为Java开发提供了强大的工具支持,尤其是在字符串处理方面,如 `Joiner`、`Splitter` 和 `CharMatcher` 等工具类,它们不仅能提升代码的可读性和维护性,还能有效提高程序的运行效率。...

    guava-r07.zip

    字符串处理是Guava的另一个亮点,它提供了Joiner和Splitter工具类,简化了字符串连接和分割操作。此外,还有CharMatcher,用于匹配字符序列,以及Strings类,包含大量静态方法来处理和验证字符串。 Guava对原生类型...

    guava-21.0-rc2 、guava-21.0-rc2-javadoc 、guava-21.0-rc2-sources

    - **字符串处理**: 提供了更多处理字符串的方法,如`Joiner`和`Splitter`,便于进行复杂的字符串操作。 - **错误处理**: 引入了`Optional`类,帮助开发者更好地处理null值问题,减少空指针异常的发生。 总的来说,...

    Guava.Net:Google的Guava库从Java到C#的移植

    5. **字符串处理**:高效的字符串操作,如 Joiner 和 Splitter。 6. **运行时检查**:Preconditions、Check 和 Verify 等工具,帮助捕获编程错误。 7. **IO 工具**:提供新的输入输出流和通道,简化文件操作。 ...

Global site tag (gtag.js) - Google Analytics