java String의 startsWith 메서드는, str이 prefix로 시작하는지를 검사하는 함수입니다. 2번째 인자에 offset을 넣을 수도 있는데요. 이는 str의 offset부터 끝까지는 부분 문자열 sub로 잡았을 때, sub가 prefix로 시작하는지를 검사합니다. 그러면, endsWith도 내부적으로는 startsWith를 쓰겠네요.

 

 쓰는 방법은 아래와 같습니다.

 

 

boolean startsWith(String prefix);

boolean startsWith(String prefix, int offset);

 

 

 보통 위에 것을 꽤 쓰는 편입니다. 그러면 이들이 어떻게 동작하는지 내부를 간단히 보아야 겠군요.

 

 


 

 먼저 String 인자만 하나 넘겨주면 그림에서의 1433번째 줄에 들어갑니다.

 

 

 그러면, 내부적으로 startsWith(prefix,0); 을 호출합니다. 어떤 문자가 string의 접두사인 것을 알아내기 위해서는, string의 0번째부터 탐색해야 하기 때문입니다.

 

 

 내부에서 약간의 전처리를 하는데요. "abcde"라는 문자열에서 "a"가 접두사인지 검사하기 위해서, 어떤 식으로 초기화를 하나 봅시다.

 

 

 5개의 변수를 초기화 합니다. 그리고 1409번째 줄에 있는 if문에 들어가게 되는데요. toffset이 0보다는 작지 않습니다. 따라서, toffset이 value.length-pc, 그러니까 string의 길이에서 prefix의 길이를 뺀 것보다 큰지를 검사하는데요. 이것은 왜 그럴까요?

 

 

 이는 |string|보다 |pat|이 더 큰 경우를 거르기 위해서입니다. 더 정확히 말하면, string의 구간 [toffset, |string|)을 부분 문자열로 가지는 sub에 대해서, |sub|보다 |pat|이 더 큰 경우를 거르기 위해서라고 보시면 되는데요.

 

 

 보라색으로 칠한 |sub|는 value.length에 toffset을 뺀 값과 같습니다. 이 값보다 |prefix|가 크다면 걸러낸다는 겁니다. 이 값은 pc이고요. 즉, value.length - toffset < pc이면, vaild 하지 않으므로 break를 걸어야 할 건데요. toffset을 우항으로, pc를 좌변으로 이항하면 value.length - pc < toffset이 됩니다. 이 조건문이 참이라면 false를 바로 리턴할 겁니다.

 

 

 1412번째 줄에 걸려있는 while문을 보면 while(--pc>=0)라고 되어 있는데요. 이것은 pc, 그러니까 |prefix|만큼 루프를 돌겠다는 겁니다. 일단 이 때, pc의 값은 전위 연산자에 의해 0이 되고, 0>=0이기 때문에 참입니다.

 

 

 

 일단 to가 가리키는 것과 po가 가리키는 것을 비교합니다. 같아요. 그러면 1회전 돌았습니다.

 

 

  다음에 --pc>=0 조건을 보면, 먼저 변수 pc의 값이 -1이 될 건데, -1>=0이 아니기 때문에 끝납니다. 따라서, while 블록을 빠져나가게 되고, true가 리턴됩니다. 사실 이 메서드는 prefix의 길이가 1이 아닐 때, 써야 하고요. prefix의 길이가 1일 때에는 따로 있습니다. 예를 들어, str이 문자열 "a"로 시작하는지 검사할 때는 어떻게 해야 할까요? 저 많은 처리를 굳이 안 해도 될 거 같은데 말입니다.

 

 이 때에는, startsWith 대신에 charAt를 이용합니다.

 

 


 이 함수가 어떻게 구현 되어 있는지 봅시다.

 

 

 그냥 경계 검사만 하고 value[index]의 값을 리턴하는 것을 볼 수 있어요. String은 내부에 배열이 있는데, 0번째 index에 있는 원소를 가지고 오겠다 하면, value[index] 이런 식으로 접근해서 가져오기만 하면 되는 셈입니다.

 

 

 예제 프로그램을 봅시다. 문자열 s의 내용은 "abcabcde..."입니다. 이것이 "abc"로 시작하는지 검사하기 위해서는 어떤 것을 쓰면 되나요? startsWith를 쓰면 됩니다. "abc"로 시작하는지 check 하기 위해서는. prefix의 길이가 3이기 때문에 일일히 charAt로 검사하는 것보다는 편합니다.

 

 

 반면에 s가 "a"로 시작하는지 알고 싶어요. prefix의 길이가 1입니다. 이 때에는 charAt(0)의 값이 'a'인지 체크하면 됩니다. 정리하면 어떠한 문자열이 pf로 시작하느냐를 검사하고 싶을 때, pf의 길이가 1이라면 charAt를 쓰시면 됩니다. 그렇지 않다면, startsWith를 쓰시면 됩니다.