Map 순회

in collection

Map 순회

Map을 사용하다보면 Map에 저장된 모든 데이터를 순회해야할 경우가 발생합니다. 여러가지 방법 중에서 아래의 3가지에 대해서 알아보았습니다.

Map 순회 방법

  1. entrySet()
  2. keySet()
  3. values()

entrySet 사용하기

entrySet은 key와 value 모두 필요한 경우에 사용하면 좋습니다. 반환값으로 Set을 반환해주기 때문에 for문을 사용해서 순회할수 있습니다.

1
2
3
4
5
6
Map<String, Object> map = new HashMap();

for (Map.Entry<String, Object> entry: map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
}

keySet 사용하기

keySet은 key 값만 필요한 경우에 사용하면 좋습니다. 마찬가지로 반환값은 Set입니다.

1
2
3
4
5
Map<String, Object> map = new HashMap();

for (String key : map.keySet()) {

}

values 사용하기

values는 value 값만 필요한 경우에 사용하면 좋습니다. 반환값은 Collection 입니다. Collection 또한 for문으로 순회할수 있습니다.

1
2
3
4
5
Map<String, Object> map = new HashMap();

for (Object value : map.values) {

}

Comment and share

DataSourceUtils

in java, api

DataSource

DataSource는 ConnectionPool을 관리하기 위한 목적으로 사용되는 객체로 DataSource를 통해서 Connection을 얻어오고 반납하는 등의 작업을 구현합니다. ConnectionPool에는 여러개의 Connection 객체가 생성되어 운용되는데, 이를 직접 웹 어플리케이션에서 다루기 힘들기 때문에 DataSource라는 개념이 도입되었습니다.

DataSourceUtils

DataSourceUtils 클래스는 JNDI에서 연결을 얻고 필요한 경우 연결을 닫는 메소드를 제공하는 기능을 제공 합니다. 그리고 DataSourceTransactionManager로 쓰레드에 기반한 연결을 지원합니다.

DataSourceUtils에서 제공하는 메소드

getConnection(DataSource dataSource)

getConnection메소드는 제공 된 DataSource를 기반으로 하여 Connection을 생성해줍니다. Connection 생성은 트랜잭션 동기화 여부에 따라 다르게 작동합니다. 만약 트랜잭션 동기화가 활성화 되어 있다면 Connection을 생성하고 트랜잭션 저장소에 바인딩 합니다. 이후 트랜잭션 동기화 작업을 종료 할때까지 getConnection메소드를 호출하면 동일한 Connection을 반환하는 것을 확인할수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class DataSourceUtilsTest {
@Autowired
DataSource dataSource;

public void testGetConnection() {
TransactionSynchronizationManager.initSynchronization();

Connection conn1 = DataSourceUtils.getConnection(dataSource);
Connection conn2 = DataSourceUtils.getConnection(dataSource);

System.out.println("동일한 인스턴스 인가요? " + conn1.equals(conn2));
}
}

트랜잭션이 동기화되어 있지 않을 경우에는 dataSource.getConnection()과 동일하게 작동합니다. 그래서 항상 새로운 Connection을 반환합니다.

1
2
3
4
5
6
7
8
9
10
11
public class DataSourceUtilsTest {
@Autowired
DataSource dataSource;

public void testGetConnection() {
Connection conn1 = DataSourceUtils.getConnection(dataSource);
Connection conn2 = DataSourceUtils.getConnection(dataSource);

System.out.println("동일한 인스턴스 인가요? " + conn1.equals(conn2));
}
}

releaseConnection(Connection conn, DataSource dataSource)

releaseConnection메소드 또한 getConnection와 비슷하게 동작 합니다. 만약 트랜잭션 동기화가 활성화 되어 있다면 트랜잭션 저장소에서 Connection을 초기화 합니다. 이때 Connection의 연결은 종료하지 않습니다. 그리고 release 후 다시 getConnection으로 Connection을 받아왔을때 동일한 값이라는 것을 확인 할수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class DataSourceUtilsTest {
@Autowired
DataSource dataSource;

public void testGetConnection() {
TransactionSynchronizationManager.initSynchronization();

Connection conn = DataSourceUtils.getConnection(dataSource);

DataSourceUtils.releaseConnection(conn, dataSource);
System.out.println("Connection이 종료 되었니? " + conn.isClosed());

Connection conn2 = DataSourceUtils.getConnection(dataSource);

System.out.println("동일한 Connection 인가요? " + conn.equals(conn2));
}
}

위와 같이 releaseConnection 메소드를 호출 하더라도 Connection은 종료되지 않는다. 단지 트랜잭션에서만 제거되었을 뿐이다. 이 때문에 사용시 주의할 필요가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class DataSourceUtilsTest {
@Autowired
DataSource dataSource;

public void testGetConnection() {
TransactionSynchronizationManager.initSynchronization();

Connection conn = DataSourceUtils.getConnection(dataSource);

System.out.println("트랜잭션 저장소에 저장 중인가? " + DataSourceUtils.isConnectionTransactional(conn, dataSource));

DataSourceUtils.releaseConnection(conn, dataSource);

TransactionSynchronizationManager.unbindResource(dataSource);
TransactionSynchronizationManager.clearSynchronization();

System.out.println("Connection이 종료 되었니? " + conn.isClosed());
System.out.println("트랜잭션 저장소에 저장 중인가? " + DataSourceUtils.isConnectionTransactional(conn, dataSource));
}
}

결론

DataSourceUtils를 사용하면 동기화된 트랜잭션의 Connection을 가져와서 사용하기에 좋다. 하지만 releaseConnection은 Connection을 종료해주는 기능이 아니므로 사용시에 주의할 필요가 있다.

트랜잭션 동기화 상태가 아닌 Connection이라면 releaseConnection메소드를 호출하면 close 해준다.

Comment and share

JSON파일 출력(파일 작성)

소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void writeJSON() {
String jsonString = "json파일에 저장할 내용",
path = "C:/json/",
fileName = "jsonTest.json";

FileWriter fileWriter = null;

File dirFile = new File(path),
fullFile = new File(path + fileName);

if (!dirFile.exists()) {
dirFile.mkdirs();
}

try {
fileWriter = new FileWriter(fullFile);
fileWriter.write(jsonString);
fileWriter.flush();
} catch(Exception e) {

} finally {
fileWriter.close();
}
}

설명

json파일을 작성하는 것은 기타 다른 파일을 작성하는 것과 별반 차이가 없다. 예제에서는 일반 string문자열을 저장하고 있지만 실제 JSON 데이터를 저장할 때도 JSONData를 JSONString으로 변환후에 저장하면 된다.

JSON파일 호출

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import com.google.gson.Gson;

public void readJSON() {
String path = "C:/json/",
fileName = "jsonTest.json";

JsonParser jsonParser = new JsonParser();

FileReader fileReader = null;

File file = new File(path + fileName);

if (file.isFile()) {
throw new Exception("존재하지 않는 파일입니다.");
}

try {
fileReader = new FileReader(file); // 1. FileReader 인스턴스를 생성합니다.

Object resultObj = gson.fromJson(fileReader, Object.class); // gson의 fromJson메서드의 첫번째 파라미터로는 Reader를 두번째 파라미터로는 Json 데이터 타입을 넘겨주면 된다.

// Map map = (Map) gson.fromJson(fileReader, Object.class); // 타입을 Object로 하고 casting 가능
// Map map = gson.fromJson(fileReader, Map.class); // 타입을 바로 Map으로 해서 casting 없이 사용 가능
} catch(Exception e) {

} finally {
fileReader.close();
}
}

설명

해당 소스코드는 구글에서 제공하는 Gson을 이용해서 parse를 한다. Gson의 fromJson은 첫번째 파라미터로 Reader와 두번째 파라미터로 데이터 타입을 받는다. 두번째 파라미터로 Object.class를 넘겨주니 모든 데이터 타입(원시 타입 포함)의 값을 오류없이 가져올수 있었다.

gson.fromJson(Reader, Type) : JSON 파일로 부터 데이터 가져오기
gson.fromJson(String, type) : JSONString 으로부터 각 데이터 타입으로 변환

Comment and share

1. 텍스트 파일 출력

1
2
3
4
5
6
7
8
9
10
String path = "./test.txt",
text = "안녕하세요\n"
+ "어서오세요\n"
+ "인사합니다";

BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(path), "UTF-8"));

writer.write(text);
writer.close();

2. 텍스트 파일 입력

1
2
3
4
5
6
7
8
9
10
11
String path = "./test.txt",
str = "";

StringBuilder sb = new StringBuilder();

BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(path), "UTF-8"));

while((str = reader.readLine()) != null) {
sb.append(str);
}

FileReader/FileWriter는 인코딩 설정이 불가능 하므로 FileInputStream/FileOuputStream을 쓰자
많은 양의 데이터를 입출력 할시에 Buffer를 쓰는것과 안 쓰는것의 차이가 크다 => 버퍼를 쓰자
InputStream/OutputStream은 단위가 바이트단위라서 한글이 깨지므로 InputStreamReader/OutputStreamReader를 쓰자

Comment and share

1. 리스트의 메서드

.retainAll(Collection)

List와 Collection에서 중복되는 값만 남기고 모두 삭제한다. 결과는 바로 List에 적용 된다

1
2
3
4
5
6
7
8
9
10
11
12
List list1 = new ArrayList();
List list2 = new ArrayList();

list1.add("아이언맨");
list1.add("헐크");

list2.add("아이언맨");
list2.add("윈터솔져");

list1.retainAll(list2);

System.out.println(list1); // [아이언맨]

.removeAll()

List와 Collection에서 중복되는 내용을 모두 삭제한다. 결과는 바로 List에 적용 된다

1
2
3
4
5
6
7
8
9
10
11
12
List list1 = new ArrayList();
List list2 = new ArrayList();

list1.add("아이언맨");
list1.add("헐크");

list2.add("아이언맨");
list2.add("윈터솔져");

list1.removeAll(list2);

System.out.println(list1); // [헐크]

2. List와 Array 변환

List => Array로 변환

1
2
3
List<String> list = new ArrayList<String>();

String[] array = list.toArray();

Array => List로 변환

이건 배열 자체적인 기능은 제공하지 않아서 배열 util인 Arrays의 asList메서드를 활용한다

1
2
3
String[] array = new String[3];

List<String> list = Arrays.asList(array);

Comment and share

  • page 1 of 1

Moon Star

author.bio


author.job