Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 30 | 31 |
Tags
- 윤년계산하기
- 인수테스트
- ServiceTest
- JXM
- 방어적 복사
- 객체지향적인 설계
- Getter Setter
- 자바 4334
- 리스코프치환원칙
- There isn't anything to compare.
- Oracle JDK와 OpenJDK의 차이
- 상수와 Enum
- PR 오류
- ControllerTest
- 백준
- JDK
- 프로젝트 패키지 구조
- 자바의 종류
- 우아한테크코스
- 자판기미션
- 우테코4기
- 자바로 만들수 있는 것
- throw 와 throws 차이
- 우테코
- java 1000번 A+B
- 블랙잭 회고
- 테스트 성능 개선
- 상근날드
- 자바 버전 다운 그레이드
- 제임스고슬링
Archives
- Today
- Total
개발새발
String.split() 본문
String.split() 의 비밀
자동차 이름 예외처리를 하다가 "pobi, jun," 처럼
문자의 제일 끝에 ,
가 오는 경우에 예외처리를 해줘야 할 것 같았는데,
예외 처리를 하지 않아도 동작에 이상이 없는것이 이상했다. 그래서 알아보기로 했다.
String.split() 의 동작 원리
평소 사용하던 split() 내부를 보니 , limit 기본이 0 으로 설정되어 있었다.
split 에 있는 limit의 3가지 역할
생각보다 limit 는 많은 역할을 하고 있었다.
limit 0 이면 맨뒤에 부터 문자가 1이상 전까지 공백이 제거됨.
(그래서 "pobi, jun,,".split(",") 일 때 배열 크기가 2 였음. )limit 음수면 공백 포함됨
limit 양수면 공백 포함, 크기가 limit만큼 제한됨
limit=3 이면 배열의 크기가 최대 3까지임.
limit의 0 일 때 예시
여기서 조금 특이한 상황이 생긴다. 일단 설명해본다.
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
|
// 1 번째
String winners ="aaa,bbb,ccc,"
String[] list = winners.split(",");
=> ["aaa","bbb","ccc"] 이때 맨뒤에 공백이 제거되어 4개가 아니라 3개만 배열로 만들어진다.
// 2 번째
String winners ="aaa,,,"
String[] list = winners.split(",");
=> ["aaa"] 맨 뒤부터 공백이면 제거되다가, 문자 사이즈가 1이상이면 공백 제거를 멈춘다.
따라서 aaa만 배열로 만들어졌다.
// 3번째
String winners ="aaa,,bb,,"
String[] list = winners.split(",");
=> ["aaa","","bb"] 맨 뒤부터 공백이면 제거되다가, 문자 사이즈가 1이상이면 공백 제거를 멈추게 되면
중간에 있는 공백은 제거가 안된다. 따라서 aaa,공백,bb 가 배열로 만들어졌다.
|
cs |
limit의 양수 일 때 예시
배열 크기가 제한된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// 1 번째
String winners ="aaa,bbb,ccc,"
String[] list = winners.split(",",2);
=> ["aaa","bbb,ccc,"] 배열 크기가 limit 가 되면 나머지는 regex로 잘리지 않고 그대로 반환된다.
// 2 번째
String winners ="aaa,,,"
String[] list = winners.split(",",6);
=> ["aaa","","",""] 공백 포함해서 4개의 배열이 리턴된다. 양수는 공백도 포함한다.
|
cs |
limit의 음수 일 때 예시
공백이 포함되고, 크기에 상관 없이 반환된다.
1
2
3
4
5
6
7
8
|
// 1 번째
String winners ="aaa,bbb,ccc,"
String[] list = winners.split(",",-1);
=> ["aaa","bbb",ccc",""] 전부다 잘려서 총 4의 크기로 반환된다.
|
cs |
내부 구조 설명
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
public String[] split(String regex, int limit) {
char ch = 0;
if (생략)
{
int off = 0;
int next = 0;
boolean limited = limit > 0; // 0 , -1 면 false, 1 이상이면 true;
ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -1) { // String 문자열 길이만큼 반복
if (!limited || list.size() < limit - 1) {
/**
limited 가 false 이거나, list.size 가 < limit -1
이 조건은 0, 이나 음수일 경우, 배열 크기에 상관없이
우리가 지정한 regex를 기준으로 값을 분리해서 반환.
**/
//
list.add(substring(off, next));
off = next + 1;
} else { // last one
// limit 가 음수이면, 그 갯수만큼 반환하기위해 break
int last = length();
list.add(substring(off, last));
off = last;
break;
}
}
// If no match was found, return this
if (off == 0)
// 만약 값이 없으면 배열 만들어서 그 문자열 그대로 리턴
return new String[]{this};
// Add remaining segment
if (!limited || list.size() < limit)
list.add(substring(off, length()));
// Construct result
int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).isEmpty()) {
/**
배열에 맨 뒤부터 공백을 확인하면서, 크기를 줄임. 만약 1이상인 문자열 만나면 그대로 반복문 나감.
**/
resultSize--;
}
}
String[] result = new String[resultSize]; // 줄여진 배열 크기만큼 생성
return list.subList(0, resultSize).toArray(result);
// 줄여진 길이만큼만 배열로 만들어서 반환 }
return Pattern.compile(regex).split(this, limit);
}
|
cs |
내용을 돌아보며 (feat. String.split () 은 중간 공백을 잡지 못한다.)
처음엔 문자열 마지막에 , 이 왔을 경우 에러가 나겠다 !!! 생각했는데
"sudal,,fobi" 이렇게 중간에 쉼표가 들어오면 에러가 날 수 있다
는 것을 알게 되었다...!!!
따라서 나는 아래와 같이 에러처리를 해주었다.
5번
느낀점
메서드 내부를 구경하다보니 시간이 훌쩍 지났다..
구현체들의 기능만 알고 사용해왔는데, 내부 로직을 살펴보니 응용해서 쓰거나,
주의해서 사용해야할 부분을 발견하게 되었다.
끈기 있게 살펴보기 잘했다는 생각이 든다.
참고
'java' 카테고리의 다른 글
Getter Setter 를 쓰지 말아야하는 이유가 뭘까? (0) | 2022.02.20 |
---|---|
HashSet, TreeSet, LinkedHashSet (0) | 2022.02.20 |
final 과 static final 의 차이? (0) | 2022.02.20 |
private 생성자를 선언하는 목적이 뭘까? (0) | 2022.02.20 |
자바란 Write Once, Run Everywhere. (0) | 2020.12.20 |