JSON에 대한 Java 객체 직렬화, GSON

구글의 GSON은 JSON 데이터를 Java 객체로 생성해주는 라이브러리입니다.

GSON에 대한 jar 라이브러리를 참조(필자는 gson-2.3.1.jar를 사용)합니다. 먼저 첫번째 예제는 JSON 문자열 대한 객체 직렬화입니다.

String strJSON = "{'name': 'Dip2K', 'age': 44 }";

Gson gson = new GsonBuilder().create();
Person person = gson.fromJson(strJSON, Person.class);
System.out.println(person);

strJSON에 담긴 JSON 데이터를 Person이라는 객체로 생성하고 있습니다. Person은 새롭게 정의한 클래스로 다음과 같습니다.

package tstThread;

import java.util.ArrayList;
import java.util.HashMap;

public class Person {
    private String name;
    private int age;
	
    private Car car = new Car("TEST");
	
    public Person(String name, int age) {	
        this.name = name;
        this.age = age;
    }
	
    @Override
    public String toString() {
        return "[" + name + ", " + age + "]";
    }
}

실행 결과는 다음과 같습니다.

[Dip2K, 44]

다음은 자바 객체를 JSON 데이터로 역직렬화하는 코드예입니다.

Person person = new Person("Dip2K", 44);

Gson gson = new GsonBuilder().create();
String strJson = gson.toJson(person);

System.out.println(strJson);

위의 코드에서 사용된 Person 클래스는 정의는 다음과 같습니다.

package tstThread;

import java.util.ArrayList;
import java.util.HashMap;

public class Person {
    private String name;
    private int age;
	
    private Car car = new Car("TEST");
	
    private ArrayList<String> array = new ArrayList<String>();
    private HashMap<String, Integer> map = new HashMap<String, Integer>();
	
    public Person(String name, int age) {	
        this.name = name;
        this.age = age;
		
        array.add("Card1");
        array.add("Card2");
        array.add("Card3");
		
        map.put("KEY1", 100);
        map.put("KEY2", 200);
        map.put("KEY3", 300);
    }
	
    @Override
    public String toString() {
        return "[" + name + ", " + age + ", " + array.get(1) + "]";
    }
}

새롭게 정의된 Person를 보면 내부 필드 객체로 Car 클래스 타입의 객체를 하나 더 갖고 있는데, 이 Car 클래스는 다음과 같습니다.

package tstThread;

public class Car {
    private String name;
	
    public Car(String name) {
        this.name = name;
    }
}

이 예제는 단순한 클래스 객체 뿐만이 아나리 객체 안에 또 다른 객체가 담겨 있을때에 대한 GSON의 역직렬화가 가능하다는 것을 확인하기 위함입니다. 실행해 보면 다음과 같습니다.

{"name":"Dip2K","age":44,"car":{"name":"TEST"},"array":["Card1","Card2","Card3"],"map":{"KEY2":200,"KEY1":100,"KEY3":300}}

이제 위의 예제에서 얻는 JSON 문자열을 다시 Person 객체로 직열화하는 예제입니다.

String strJSON = "{'name':'Dip2K','age':44,'car':{'name':'TEST'},'array':['Card1','Card2','Card3'],'map':{'KEY2':200,'KEY1':100,'KEY3':300}}";

Gson gson = new GsonBuilder().create();
Person person = gson.fromJson(strJSON, Person.class);
System.out.println(person);

결과는 다음처럼 직열화가 잘된것을 확인할 수 있습니다.

[Dip2K, 44, Card2]

[Java] 두 문자열간의 유사도 구하기

두개의 문자열이 있을때, 얼마나 유사한지를 백분율의 개념인 0~1사이의 값으로 확인할 수 있을까? 즉 똑같은 문자열이라면 1을 전혀 다른 문자열이라면 0이라는 값으로 말이다. 구글링해보니 edit distance 계산을 통해 얻을 수 있단다. 가장 일반적은 구현체는 Levenshtein의 Distance Algorithm이라고 하고, 그 구현 함수는 다음과 같다. (출처: http://rosettacode.org/wiki/Levenshtein_distance#Java)

private double similarity(String s1, String s2) {
    String longer = s1, shorter = s2;
	
    if (s1.length() < s2.length()) {
        longer = s2; 
        shorter = s1;
    }
	
    int longerLength = longer.length();
    if (longerLength == 0) return 1.0;

    return (longerLength - editDistance(longer, shorter)) / (double) longerLength;
}

private int editDistance(String s1, String s2) {
	s1 = s1.toLowerCase();
    s2 = s2.toLowerCase();
    int[] costs = new int[s2.length() + 1];
    
    for (int i = 0; i <= s1.length(); i++) {
        int lastValue = i;
        for (int j = 0; j <= s2.length(); j++) {
            if (i == 0) {
            	costs[j] = j;
            } else {
                if (j > 0) {
                    int newValue = costs[j - 1];
                    
                    if (s1.charAt(i - 1) != s2.charAt(j - 1)) {
                    	newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1;
                    }
                    
                    costs[j - 1] = lastValue;
                    lastValue = newValue;
                }
            }
        }
        
        if (i > 0) costs[s2.length()] = lastValue;
    }
    
    return costs[s2.length()];
}

사용은 similarity 함수에 비교할 문자열 2개를 지정하면 비슷한 정도가 0~1 사이의 값으로 반환된다.