자바 커스텀 Array

1 개요[ | ]

자바 Array
  • 자바 TreeMap을 기반으로 PHP 스타일의 배열을 구현한 것이다.
참고로 PHP의 Array 자료구조가 원래 TreeMap이다.
단, json, yaml 인코딩시에 인덱스가 0, 1, 2, ... 형식에 완전히 부합하는 경우는 리스트로 판단한다. → PHP 배열 맵인가 리스트인가
  • PHP처럼 array( i1, i2, i3 ), array( k => v ) 구조를 지원하기는 어려워 보인다.
  • 대신... 1) 체인 사용, 2) JSON 입출력, 3) YAML 입출력이 가능하다.
  • 버그가 있을거야 아마;;

2 클래스[ | ]

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.TreeMap;

import org.springframework.boot.json.JsonParser;
import org.springframework.boot.json.JsonParserFactory;
import org.yaml.snakeyaml.Yaml;

import com.google.gson.Gson;

public class Array extends TreeMap<String, Object> {
	private static final long serialVersionUID = 1L;
	private Object value = null;

	public static Array fromJson(String jsonString) {
		Array arr = new Array();
		JsonParser parser = JsonParserFactory.getJsonParser();
		try {
			List<Object> list = parser.parseList(jsonString);
			for( Object obj: list ) arr.push(obj);
		}
		catch(Exception e){
			LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) parser.parseMap(jsonString);
			for( java.util.Map.Entry<String, Object> m: map.entrySet() ) arr.put(m.getKey(), m.getValue());
		}
		return arr;
	}
	public static Array fromYaml(String yamlString) {
		@SuppressWarnings("unchecked")
		Map<String,Object> map = (Map<String, Object>) new Yaml().load(yamlString);
		Array arr = new Array();
		for (Map.Entry<String, Object> entry : map.entrySet()) {
		    arr.put(entry.getKey(), entry.getValue());
		}
		return arr;
	}
	
	public Array() {}
	public Array(Object obj) {
		this.value = obj;
	}

	public Array(Object[] objs) {
		for( Object obj: objs ) this.push(obj);
	}
	public Array(List<Object> objs) {
		for( Object obj: objs ) this.push(obj);
	}
	public Array(Set<String> objs) {
		for( Object obj: objs ) this.push(obj);
	}
	public Array(Collection<Object> objs) {
		for( Object obj: objs ) this.push(obj);
	}
	
	public Array get(int i) {
		return get(String.valueOf(i));
	}
	public Array get(String str) {
		Object item = super.get(str);
		if( item.getClass() == Array.class ) return (Array) item;
		return new Array(item);
	}

	public Integer getInteger() {
		return (int) value;
	}
	public String getString() {
		return (String) value;
	}
	public Object getObject() {
		return value;
	}	
	
	public List<Integer> getIntegerList() {
		List<Integer> list = new ArrayList<Integer>();
		for( Object obj: this.values() )  {
			list.add((Integer) obj);
		}
		return list;
	}
	public List<String> getStringList() {
		List<String> list = new ArrayList<String>();
		for( Object obj: this.values() )  {
			list.add(obj.toString());
		}
		return list;
	}
	public List<Object> getObjectList() {
		List<Object> list = new ArrayList<Object>();
		for( Object obj: this.values() )  {
			list.add(obj);
		}
		return list;
	}	
	
	public Array push(Object obj) {
		int max = -1;
		for (String indexString : this.keySet()) {
			if( isInt(indexString) ) {
				int index = Integer.parseInt(indexString);
				if( index > max ) max = index; 
			}
		}
		return put(max + 1, obj);
	}
	public Array put(int i, Object obj) {
		return put(String.valueOf(i), obj);
	}
	public Array put(String key, Object obj) {
		super.put(key, obj);
		return this;
	}

	public Array keys() {
		return new Array(this.keySet());
	}
	public Array values(boolean dummy) {
		return new Array(this.values());
	}

	public String toString() {
		if( value != null ) return value.toString();
		if( isList() ) return this.values().toString();
		return super.toString();
	}
	public String toJson() {
		return new Gson().toJson( toMapAndList() );		
	}
	public String toYaml() {
		Yaml yaml = new Yaml();
		@SuppressWarnings("unchecked")
		Map<String,Object> map = (Map<String, Object>) yaml.load( toJson() );
		return yaml.dump(map);
	}

	private static boolean isInt(String input) {
		try {
			Integer.parseInt(input);
			return true;
		}
		catch (NumberFormatException e) {
			return false;
		}
	}
	private boolean isList() {
		int i=0;
		for (String key : this.keySet()) {
			if( !key.equals( String.valueOf(i) ) ) return false;
			i++;
		}
		return true;
	}
	private Object toMapAndList() {
		if( value != null ) return value;
		if( !isList() ) return this; 
		List<Object> list = new ArrayList<Object>();
		for( String key: this.keySet() ) {
			list.add( get(key).toMapAndList() );
		}
		return list;
	}
}

3 사용예시 1: 기본사용[ | ]

Array arr1 = new Array();
arr1.push("A");
arr1.push("B");
arr1.push("C");

Array arr2 = new Array();
arr2.put("a", "Hello");
arr2.put("b", "World");

Array arr3 = new Array();
arr3.push(arr1);
arr3.push(arr2);

System.out.println( arr3 );
System.out.println( arr3.get(0) );
System.out.println( arr3.get(1) );
// [[A, B, C], {a=Hello, b=World}]
// [A, B, C]
// {a=Hello, b=World}

System.out.println( arr3.keySet() );
System.out.println( arr3.values() );
// [0, 1]
// [[A, B, C], {a=Hello, b=World}]

System.out.println( arr3.get(0).get(0) );
System.out.println( arr3.get(0).get(1) );
System.out.println( arr3.get(0).get(2) );
// A
// B
// C

System.out.println( arr3.get(1).get("a") );
System.out.println( arr3.get(1).get("b") );
// Hello
// World

4 사용예시 2: JSON 입력[ | ]

Array arr1 = new Array("[1,2,3]");
Array arr2 = Array.fromJson("{\"a\":\"Hello\",\"b\":\"World\"}");
Array arr3 = new Array();
arr3.push(arr1);
arr3.push(arr2);
arr3.push("안녕하세요");
arr3.get(1).put("b", "월드");
System.out.println( arr3 );
System.out.println( arr3.toJson() );
System.out.println( arr3.get(1).get("a") );
// [[1, 2, 3], {a=Hello, b=월드}, 안녕하세요]
// [[1,2,3],{"a":"Hello","b":"월드"},"안녕하세요"]
// Hello

5 사용예시 3: 체인 입력[ | ]

Array arr = new Array()
		.push( new Array()
				.push("A")
				.push("B")
				.push("C") )
		.push( new Array()
				.put("a", "안녕")
				.put("b", "World") );
System.out.println( arr );
System.out.println( arr.toJson() );
// [[A, B, C], {a=안녕, b=World}]
// [["A","B","C"],{"a":"안녕","b":"World"}]

6 사용예시 4: YAML[ | ]

String yamlString = "---" 
		+ "\n" + "men: [John Smith, Bill Jones]"
		+ "\n" + "women:"
		+ "\n" + "  - Mary Smith"
		+ "\n" + "  - Susan Williams";
Array arr = Array.fromYaml(yamlString);

System.out.println(arr);
// {men=[John Smith, Bill Jones], women=[Mary Smith, Susan Williams]}
System.out.println(arr.toJson());
// {"men":["John Smith","Bill Jones"],"women":["Mary Smith","Susan Williams"]}
System.out.println(arr.toYaml());
// men: [John Smith, Bill Jones]
// women: [Mary Smith, Susan Williams]

7 사용예시 5: 기타[ | ]

Array arr = new Array("aa bb cc".split(" "));
System.out.println(arr);
// [aa, bb, cc]

8 같이 보기[ | ]