1. 개요 변환에는 크게 두 가지 종류가 있습니다. 자료구조의 변환. 예를 들어, List를 Integer[]로의 변환. (타입은 유지되고 자료구조만 변환하고 싶은 경우) 자료형의 변환. 예를 들어, int 타입을 Integer 타입으로 변환하고 싶은 경우 해당 포스팅은 자료형을 변환시키고자 하는 것으로 위에서 두 번째 경우에 해당합니다. 그럼 어떤 경우에 자료형을 변환해야할까요? 🤔 int[] 배열을 오름차순 정렬하고싶다면 Arrays.sort()로 간단히 해결할 수 있습니다. 하지만, 내림차순 정렬을 하고싶다면 두 번째 파라미터로 Comparator를 정의해줘야하는데, 이때 value타입은 불가능합니다. 2. Integer[] ---> int[] 로의 변환 Java8의 람다와 스트림을 활용하는 방법으..
정규 표현식은 예시로 살펴보는게 가장 좋은 학습 방법인 것 같다. String#replaceAll 메서드를 이용한 정규 표현식 예 첫 번째 요구사항 --- 전체 URL에서 도메인의 정보만 뽑아내고 싶다. @Test public void 정규_표현식_테스트() { String str = "https://pangtrue.tistory.com/post/100"; str = str.replaceAll("(?i:https?://([^/]+)/.*)", "$1"); assertEquals(str, "pangtrue.tistory.com"); } 위 regexp를 분석해보자. 먼저, regexp에는 non-capturing group과 capturing group 두 가지의 그룹 방식이 있다. (?:) ---> no..
Map을 순회하는 방법을 정리해보겠습니다. 첫 번째, Iterator를 통해 접근하기 Map map = new HashMap(); Iterator keys = map.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); map.get(key); } 두 번째, entrySet으로 접근하기. Map은 하나의 원소로 Key-Value 묶음을 가지기 때문에 원소란 표현 대신 Entry라고 표현합니다. Map map = new HashMap(); for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); } 세 번째..
웹 애플리케이션을 유지보수하거나 추가 개발하는 과정에서 특정 라이브러리의 기능을 테스트해보고 싶은 경우가 많이 있다. 나 같은 경우 간단하게 StringUtils의 메서드 결과 값이 어떻게 나오는지 테스트해보고 싶었는데, 이런 간단한 작업을 하기 위해 메인 소스 영역에 아래와 같은 코드를 넣은 후, 웹 애플리케이션을 구동하는걸 반복하다보니 이건 아니다 싶었다.. int idx = StringUtils.indexOf("abcdefg_1234", '_'); log.info("result : ", idx); 반면에 src/test/java 영역에 해당 코드를 작성하면 결과 값을 가볍게 바로 확인할 수 있다. public class StringUtilsTest { @Test public void test() {..
1. XML 파싱 JSON이 편리하고 많이 사용되는게 사실이지만, XML 또한 많이 사용되는 것도 사실입니다. 그렇기 때문에, 데이터를 XML로 만드는 것과 XML을 파싱해서 데이터를 이용하는 것 둘 다 할 줄 알아야합니다. XML 파싱이라는 작업이 워낙에 일반적이다보니 Java는 XML 파서를 내장하고 있습니다. 2. 내장 라이브러리를 사용한 XML 파싱 예제 아래와 같은 구조의 XML 파일이 있다고하겠습니다. Alsa 25 Bob 28
1. JVM이란? C 프로그램의 실행 프로세스를 한 번 생각해보자. preprocessor를 거쳐 코드가 확장된다. 확장된 코드는 compiler를 통해 어셈블리 코드로 변환된다. 변환된 어셈블리 코드는 assembler를 통해 바이트 코드를 가진 .obj 파일로 변환된다. .obj 파일은 linker를 통해 외부의 라이브러리 코드와 연결시킨 후, 실행 파일(.exe 등)을 생성한다. 실행이 가능해진 코드는 loader를 통해 메모리에 로드되고, 기계는 이를 해석하며 그에 따라 동작한다. C 프로그램은 위와 같은 프로세스를 머신에서 수행하고, Java는 가상머신을 이용해 이와 같은 프로세스를 처리한다. JVM이 하는 일은 크게 3가지 코드를 로드하고, 검증하고, 실행한다. OS로부터 메모리를 할당받아 관..
try-with-resources는 try(...)문 안에서 선언된 객체에 대해서 try가 종료될 때 자동으로 자원을 해제( close() 메서드 호출 )해주는 기능이다. 단, try( ... ) 문 안에 선언된 객체가 AutoClosable 인터페이스를 구현한 객체여야한다. public interface AutoCloseable { void close() throws Exception; }
java.nio 패키지 참고로 nio는 New I/O의 약자. ( non-blocking의 약자인줄 알았는데 아님. ) 기존의 java.io 패키지를 대체하기 위해 새롭게 나온 패키지다. 과거 Java I/O는 C/C++과 비교해 매우 많이 느리다는 평가가 많았는데, 이유는 두 가지다. 커널 버퍼를 직접적으로 핸들링할 수 없다. blocking I/O다. 기존의 io 패키지에서는 데이터가 흘러가는 통로를 stream이라는 용어를 써서 표현했고, 새로운 nio 패키지에서는 데이터가 흘러가는 통로를 channel이라는 용어를 써서 표현한다. Stream VS Channel Stream의 특징은 다음과 같다. 읽기/쓰기를 할때 InputStream과 OutputStream으로 구분해서 사용했다. ( 단방향 )..
CAS ( Compare And Swap ) Atomic은 CAS 방식에 기반하여 동기화 문제를 해결한다. CAS란 변수가 기존에 가지고 있던 값이 내가 예상하는 값과 일치하는 경우에만 새로운 값을 할당하는 것. public class AtomicDemo { private int val; public boolean compareAndSwap(int oldVal, int newVal) { if (val == oldVal) { val = newVal; return true; } return false; } } 간단하게, 값을 변경하기 전에 한번 더 확인해주는거라 보면됨. Java에서 제공하는 Atomic Type은 이러한 CAS를 하드웨어(CPU)의 도움을 받아 한 번에 단 하나의 스레드만 변수의 값을 변경..
volatile 키워드 volatile 키워드로 선언된 변수는 Main Memory에 저장된다. 보통 변수에 read/write를 하게되면 CPU Cache까지만 바라보고 작업을 진행하는데, 이를 Main Memory까지 확장시키는 것. 아래 그림을 보자. 멀티 스레드 프로그래밍에서 각 스레드는 최초 메인 메모리에서 변수의 값을 읽어온후, 이를 CPU Cache에 저장한다. 그 다음부터는 변수 값을 참조하기 위해 CPU Cache까지만 보기 때문에 두 스레드가 같은 변수의 값을 read/write한다면 값의 불일치 문제가 발생할 수 있다. CPU Cache가 아닌 Main Memory에서 변수의 값을 읽고/쓴다면 변수 값의 동기화 문제가 해결될 수 있다. ( volatile로 변수를 선언. ) 참고자료 ..
Java는 멀티 스레드 프로그래밍에서의 동기화 문제에 대해 3가지 방법을 제시한다. synchronized 키워드 volatile 변수 Atomic 클래스 이 세가지 중에서 synchronized 키워드에 대해 정리해보자. synchronized 키워드 Java에서 synchronized 키워드를 활용하는 방법은 두 가지다. synchronized 메서드 ( 메서드 자체에 해당 키워드를 적용 ) synchronized 블럭 ( 메서드 내부에 동기화가 필요한 로직에만 synchronized 블럭으로 감싸는 형태 ) 먼저 메서드 자체에 synchronized 키워드를 붙여줬을 때. public class DemoSynchronization { private String mMessage; public stat..
Annotation 어노테이션은 잘만 사용하면 정말 유용한 Java의 구문이다. 기본적인 종류는 몇 가지에 한정되지만, 내가 원하는대로 커스텀 어노테이션을 만들어 사용할 수 있다. 어노테이션의 본질적인 목적은 소스 코드에 메타데이터를 표현하는 것. 하지만 단순히 부가적인 표현을 넘어, reflection을 이용하면 어노테이션 지정만으로 원하는 클래스를 주입하는 것도 가능하다. Built-in Annotation Java에서 기본적으로 제공하는 어노테이션은 다음과 같다. @Override : 오버라이딩할 때 사용. @Deprecated : 더이상 사용되지않는 메서드를 지정한다. 해당 어노테이션이 붙은 메서드를 사용했을 시 컴파일 경고. @SuppressWarnings : 컴파일 경고를 무시한다. @Safe..