Guava의 Splitter 예시의 반대인 Joiner 예시이다. 

trimResults()와 omitEmptyString()가 많이 쓰인다. 


Guava의 Joiner.on과 좀 다르게 다양한 파싱을 할 수 있도록 on() 뿐 아니라 onPattern(), on(CharMatcher) 메솓,등을 사용할 수 있다. 특정 길이(fixedLength)나, 파싱 갯수(limit)를 활용하여 파싱할 수 있다.



  /*
List
*/
@Test
public void splitterTest1() {
String input = "samuel,kent, flynn";
// not trim
List<String> list = Splitter.on(",").splitToList(input);
logger.info("{}", list);

// trim
List<String> list1 = Splitter.on(",").trimResults().splitToList(input);
logger.info("{}", list1);
}

// 결과
// [samuel, kent, flynn]
// [samuel, kent, flynn]

/*
empty string
*/
@Test
public void splitterTest2() {
String input = "samuel,kent,flynn,,";
List<String> list = Splitter.on(",").trimResults().splitToList(input);
logger.info("before omit - {}", list);

List<String> list1 = Splitter.on(",").omitEmptyStrings().splitToList(input);
logger.info("after omit - {}", list1);
}

// 결과
// before omit - [samuel, kent, flynn, , ]
// after omit - [samuel, kent, flynn]

/*
Map
*/
@Test
public void splitterTest3() {
String input = "name=samuel&age=41&department=server&id=1001237";
Map<String, String> map = Splitter.on("&").withKeyValueSeparator("=").split(input);
MapUtils.debugPrint(System.out, "map", map);
}

/*
결과
map =
{
name = samuel java.lang.String
age = 41 java.lang.String
department = server java.lang.String
id = 1001237 java.lang.String
} java.util.Collections$UnmodifiableMap
*/


/*
Map, multiple separator, onPattern/anyOf
*/
@Test
public void splitterTest4() {
String input = "name=samuel&age=41&department=server,id=1001237";
Map<String, String> map = Splitter.onPattern("[&|,]").withKeyValueSeparator("=").split(input);
MapUtils.debugPrint(System.out, "map", map);

map = Splitter.on(CharMatcher.anyOf("[&|,]")).withKeyValueSeparator("=").split(input);
MapUtils.debugPrint(System.out, "map", map);
}
/*
결과
map =
{
name = samuel java.lang.String
age = 41 java.lang.String
department = server java.lang.String
id = 1001237 java.lang.String
} java.util.Collections$UnmodifiableMap
*/

@Test
public void splitterTest5() {
String input = "111222333444555";
List<String> list = Splitter.fixedLength(3).splitToList(input);
logger.info("{}", list);
}
// 결과
// [111, 222, 333, 444, 555]


/*
limit
*/
@Test
public void splitterTest6() {
String input = "111,22,33333,444,555";
List<String> list = Splitter.on(",")
.limit(2)
.splitToList(input);
logger.info("{}", list);

list = Splitter.on(",")
.limit(3)
.splitToList(input);
logger.info("{}", list);

list = Splitter.on(",")
.limit(4)
.splitToList(input);
logger.info("{}", list);

list = Splitter.on(",")
.limit(5)
.splitToList(input);
logger.info("{}", list);

list = Splitter.on(",")
.limit(6)
.splitToList(input);
logger.info("{}", list);
}

// 결과
// [111, 22,33333,444,555]
// [111, 22, 33333,444,555]
// [111, 22, 33333, 444,555]
// [111, 22, 33333, 444, 555]
// [111, 22, 33333, 444, 555]


Posted by '김용환'
,


Guava의 Joiner를 테스트한 코드이다. 

Map이나 List의 내용을 특정 포맷(Joiner.on)에 맞춰 보여줄 수 있다. 이 과정에서 널 체크(skipNull)도 가능하다.


예를 들어, Map이나 List의 내용을 http 리퀘스트 url의 파라미터와 같은 포맷으로도 만들 수 있다. 


private final Logger logger = LoggerFactory.getLogger(SplitterJoinerTest.class);

/*
List -> String
*/
@Test
public void joinerTest1() {
List counts = Lists.newArrayList(1, 2, 3, 4, 5);
List names = Lists.newArrayList("samuel", "kent", "flynn");

logger.info("count:{}, names:{}", Joiner.on(",").join(counts), Joiner.on(",").join(names));
} // 결과 - count:1,2,3,4,5, names:samuel,kent,flynn

/*
sequence of String -> String
*/
@Test
public void joinerTest2() {
logger.info("type:{}", Joiner.on("|").join("a", "b", "c"));
} // 결과 - type:a|b|c

/*
Map -> String
*/
@Test
public void joinerTest3() {
ImmutableMap<String, Object> map = ImmutableMap.of("name", "samuel", "age", 41, "department", "server", "id", 1001237);
Joiner.MapJoiner mapJoiner = Joiner.on('&').withKeyValueSeparator("=");
logger.info("{}" , mapJoiner.join(map));
} //결과 - name=samuel&age=41&department=server&id=1001237

/*
null checking
*/
@Test
public void joinerTest4() {
logger.info("{}" ,Joiner.on(",").skipNulls().join(Lists.newArrayList("samuel", "kent", null)));
try {
logger.info("{}", Joiner.on(",").join(Lists.newArrayList("samuel", "kent", null)));
} catch (java.lang.NullPointerException e) {
e.printStackTrace();
}
} //결과 - samuel,kent java.lang.NullPointerException at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:213)

@Test
public void joinerTest5() {
List<List<String>> list = Lists.newArrayList(
Lists.newArrayList("samuel", "jonathan", "ben", "bernad"),
Lists.newArrayList("ted", "alden", "kyle", "clark")
);

String result = Joiner.on(";").join(Iterables.transform(list,
new Function<List<String>, String>() {
@Override
public String apply(List<String> input) {
return Joiner.on("-").join(input);
}
}));

logger.info("{}", result);
} //결과 : samuel-jonathan-ben-bernad;ted-alden-kyle-clark

@Test
public void joinerTest6WithJava8() {
List<List<String>> list = Lists.newArrayList(
Lists.newArrayList("samuel", "jonathan", "ben", "bernad"),
Lists.newArrayList("ted", "alden", "kyle", "clark")
);

String result = Joiner.on(";").join(Iterables.transform(list,
s -> Joiner.on("-").join(s)));

logger.info("{}", result);
} //결과 : samuel-jonathan-ben-bernad;ted-alden-kyle-clark


Posted by '김용환'
,



DB SQL(insert, replace..)의 values에 여러 데이터를 한 번에 저장해야 할 일이 있을 때, 

List 객체를 순회하면서 데이터를 포맷을 tuple형식처럼 만들어야 하는 경우가 있는데. 맨 끝 요소에 대해서는 , 를 제외시켜야 한다.



(a, b, c, d), (e, f, g, h), 


->


(a, b, c, d), (e, f, g, h)




이럴 때 쓸만한 utility로 guava에 Splitter와 Jointer가 있다. 이를 활용하면 맨 끝의 ,는 다 사라진다. 



import com.google.common.base.Joiner;

import com.google.common.base.Splitter;

import org.junit.Test;


public class RemovalCommanFromTailOfStringTest {


static Splitter splitter = Splitter.on(',').omitEmptyStrings().trimResults();

static Joiner joiner = Joiner.on(',').skipNulls();


public static String cleanUpCommas(String string) {

return joiner.join(splitter.split(string));

}


@Test

public void test() {

System.out.println(RemovalCommanFromTailOfStringTest.cleanUpCommas("3,4,5,,,,,,,,,,,,"));

System.out.println(RemovalCommanFromTailOfStringTest.cleanUpCommas(",,,,,,,,,,,,,,,,3,4,5,6,"));

System.out.println(RemovalCommanFromTailOfStringTest.cleanUpCommas("3,4,5                               ,"));

System.out.println(RemovalCommanFromTailOfStringTest.cleanUpCommas("(a),(b),(c),(d),"));

}


}



출력


3,4,5

3,4,5,6

3,4,5

(a),(b),(c),(d)


'general java' 카테고리의 다른 글

Guava의 Joiner 예시  (0) 2016.03.13
Guava의 Joiner 예시  (0) 2016.03.13
zookeeper Max 노드(znode) 크기  (0) 2016.01.20
[springboot] mybatis  (0) 2016.01.12
[mybatis] spring4에서 사용할 수 있는 ibatis 지원  (0) 2016.01.12
Posted by '김용환'
,




zookeeper의 노드 크기(znode)는 최대 값은 1M이며, jute.maxbuffer로 변경할 수 있다. 



https://zookeeper.apache.org/doc/r3.3.2/zookeeperAdmin.html

jute.maxbuffer:

(Java system property: jute.maxbuffer)

This option can only be set as a Java system property. There is no zookeeper prefix on it. It specifies the maximum size of the data that can be stored in a znode. The default is 0xfffff, or just under 1M. If this option is changed, the system property must be set on all servers and clients otherwise problems will arise. This is really a sanity check. ZooKeeper is designed to store data on the order of kilobytes in size.



코드를 살펴보면, 디폴트 0xfffff로 되어 있으며, 10진수로 1,048,575 bytes(약 1 MB)까지 저장할 수 있다.


https://github.com/apache/zookeeper/blob/trunk/src/java/main/org/apache/jute/BinaryInputArchive.java

static public final int maxBuffer = Integer.getInteger("jute.maxbuffer", 0xfffff);






Posted by '김용환'
,

[springboot] mybatis

general java 2016. 1. 12. 19:47


mybatis를 spring boot에서도 쓸 수 있다. 


https://github.com/mybatis/mybatis-spring-boot


<dependency>

    <groupId>org.mybatis.spring.boot</groupId>

    <artifactId>mybatis-spring-boot-starter</artifactId>

    <version>1.0.0</version>

</dependency>


Posted by '김용환'
,



spring4에서 ibatis 코드를 싹 빼 버려서, 이제는 spring이 batis를 지원하지 않아 많이 아쉬웠다. 



ibatis를 쓰는 spring 3 프로젝트를 spring 4 프로젝트로 올릴려면, spring ibatis 코드를 spring4 기반 프로젝트에 소스를 모두 복사해야 동작한다...



mybatis 팀이 spring3의 ibatis 코드를 spring4에서 돌아갈 수 있도록 'mybatis-2-spring'을 지원한다고 발표했다. 아직 github는 보이지 않지만, 발표했으니. 지켜봐야할 것 같다. 


* 출처 


http://blog.mybatis.org/


Sunday, November 8, 2015

Spring 4 got you down with no ibatis support - no worries Mybatis has your back

Spring is well on it's way to leaving 3 behind.  For ibatis users that for one reason or another are stuck to ibatis, but want to just make the jump to spring 4, there is a dilemma.  This dilemma roots in the fact that spring team dropped ibatis in spring 4.  Until now this meant that upgrading to spring 4 required upgrading ibatis to mybatis and mybatis-spring.  Well in order to mitigate risk to those that need it, mybatis team has decided to extract the spring 3 ibatis support into a new mybatis project called 'mybatis-2-spring'.  Better still, we go one step further and have released a fresh copy of 'mybatis-2'.  So there you have it, all of the users out there dealing with legacy code, mybatis is no longer directly tied into the mix resulting in higher risk in upgrading.  With that said, enjoy what's left in the ibatis land as we resurrect the past.


Cheers!


Jeremy Landis and MyBatis Team


Posted by '김용환'
,


Spring Boot의 devtools를 사용할 때, 항상 코드를 재시작하지 않는 환경이 있을 수 있다. 이 때는 spring.devtools.restart.enabled의 속성 값을 사용한다. 

if (phase != PHASE.Local) {
    System.setProperty("spring.devtools.restart.enabled", "false");

}


출처 

https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html




Posted by '김용환'
,


play1 에서 분명 문제 없는데, 아래와 같이 컴파일 에러가 발생할 수 있다.


 It is indirectly referenced from required .class files



play clean 후, play deps 를 실행하면 된다.

lib dependency가 꼬여서 문제가 발생하는 것이다.


Posted by '김용환'
,



Resources.getResource() 메소드는 classpath를 기준으로 파일을 읽는다. 만약 절대적인 위치를 가르키면, Error를 발생한다.

하지만 절대적인 path를 알고 있다면, Guava의 Files.toString()을 사용하면 파일은 잘 받을 수 있다.


@Test

public void test() throws IOException {

URL url = Resources.getResource("api.thrift"); // 내부 class path를 읽도록 함.

//URL url = Resources.getResource("file:/build.properties"); // Error발생

System.out.println(url);

String text = Resources.toString(url, Charsets.UTF_8);

System.out.println(text);

}


@Test

public void test2() throws IOException {

// 절대 path 이용

String text = Files.toString(new File("/build.properties"), Charsets.UTF_8);

System.out.println(text);

}



Files.toString()과 함께 잘 사용하는 것은 Files.hash() 메소드이다. md5 hash 값을 얻어오려면, Files.hash(buildFile, Hashing.md5()) 메소드를 활용한다.



@Test

public void test2() throws IOException {

File buildFile = new File("/mydev/util/build.properties");

String hash = Files.hash(buildFile, Hashing.md5()).toString();

System.out.println(hash);

}



e7eba1bdbd13e21d2b7ae3d110e9ce9d


Posted by '김용환'
,


Guava의 Immutable Collection에 put/add 를 호출하면, UnsupportedOperationException 예외가 발생한다. 


public class ImmutableTest {

 @Test 

 public void test() {

  ImmutableList<String> list = ImmutableList.of("1", "2");

  list.add("put");

 }

}


에러내용


java.lang.UnsupportedOperationException

at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:96)




참고 : guava source


 public abstract class ImmutableCollection<E> extends AbstractCollection<E>

    implements Serializable {


 /**

   * Guaranteed to throw an exception and leave the collection unmodified.

   *

   * @throws UnsupportedOperationException always

   * @deprecated Unsupported operation.

   */

  @Deprecated

  @Override

  public final boolean add(E e) {

    throw new UnsupportedOperationException();

  }


Posted by '김용환'
,