문자열 만들기
Java 프로그래밍에서 널리 사용되는 문자열은 문자의 시퀀스입니다. Java 프로그래밍 언어에서 문자열은 객체입니다.
Java 플랫폼은 문자열을 생성하고 조작할 수 있는 String 클래스를 제공합니다.
문자열을 만드는 가장 직접적인 방법은 작성하는 것입니다:
String greeting = "Hello world!";이 경우 “Hello world!”는 문자열 리터럴(코드에서 큰따옴표로 묶인 일련의 문자)입니다. 컴파일러는 코드에서 문자열 리터럴을 발견할 때마다 해당 값(이 경우 Hello world!)을 가진 String 객체를 생성합니다.
다른 객체와 마찬가지로 new 키워드와 생성자를 사용하여 String 객체를 만들 수 있습니다. String 클래스에는 문자 배열과 같은 다양한 소스를 사용하여 문자열의 초기 값을 제공할 수 있는 13개의 생성자가 있습니다:
char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
String helloString = new String(helloArray);
System.out.println(helloString);이 코드 스니펫의 마지막 줄에는 hello가 표시됩니다.
Note:
String클래스는 불변이므로 일단 생성된String객체는 변경할 수 없습니다.String클래스에는 문자열을 수정하는 것으로 보이는 여러 가지 메서드가 있으며, 그 중 일부는 아래에서 설명합니다. 문자열은 불변이므로 이러한 메서드가 실제로 수행하는 작업은 연산 결과를 포함하는 새 문자열을 생성하고 반환하는 것입니다.
문자열 길이
객체에 대한 정보를 얻는 데 사용되는 메서드를 접근자 메서드라고 합니다. 문자열에 사용할 수 있는 접근자 메서드 중 하나는 문자열 객체에 포함된 문자 수를 반환하는 length() 메서드입니다. 다음 두 줄의 코드가 실행된 후 len은 17과 같습니다:
String palindrome = "Dot saw I was Tod";
int len = palindrome.length();팔린드롬(palindrome) 은 대칭인 단어 또는 문장으로, 대소문자와 구두점을 무시하고 앞뒤 철자가 동일합니다. 다음은 팔린드롬 문자열을 반전시키는 짧고 비효율적인 프로그램입니다. 이 프로그램은 0부터 카운트하여 문자열의 th 문자를 반환하는 String 메서드 charAt(i)를 호출합니다.
public class StringDemo {
public static void main(String[] args) {
String palindrome = "Dot saw I was Tod";
int len = palindrome.length();
char[] tempCharArray = new char[len];
char[] charArray = new char[len];
// put original string in an
// array of chars
for (int i = 0; i < len; i++) {
tempCharArray[i] =
palindrome.charAt(i);
}
// reverse array of chars
for (int j = 0; j < len; j++) {
charArray[j] =
tempCharArray[len - 1 - j];
}
String reversePalindrome =
new String(charArray);
System.out.println(reversePalindrome);
}
}프로그램을 실행하면 이 출력이 생성됩니다:
doT saw I was toD문자열 반전을 수행하기 위해 프로그램은 문자열을 문자 배열로 변환하고(첫 번째 for 루프), 배열을 두 번째 배열로 반전시킨 다음(두 번째 for 루프), 다시 문자열로 변환해야 했습니다. String 클래스에는 문자열 또는 문자열의 일부를 문자 배열로 변환하는 메서드인 getChars()가 포함되어 있으므로 위 프로그램의 첫 번째 for 루프를 다음과 같이 바꿀 수 있습니다.
palindrome.getChars(0, len, tempCharArray, 0);
문자열 연결하기
String 클래스에는 두 문자열을 연결하는 메서드가 포함되어 있습니다:
string1.concat(string2); 이 메서드는 끝에 string2가 추가된 string1인 새 문자열을 반환합니다.
다음과 같이 문자열 리터럴과 함께 concat() 메서드를 사용할 수도 있습니다:
"My name is ".concat("Rumplestiltskin");문자열은 다음과 같이 + 연산자로 연결되는 것이 더 일반적입니다.
"Hello," + " world" + "!"그 결과
"Hello, world!"+ 연산자는 출력문에서 널리 사용됩니다. 예를 들어
String string1 = "saw I was ";
System.out.println("Dot " + string1 + "Tod");다음을 출력합니다.
Dot saw I was Tod이러한 연결은 모든 객체가 혼합될 수 있습니다. String이 아닌 각 객체에 대해 해당 객체의 toString() 메서드를 호출하여 String으로 변환합니다.
Note: Java SE 15 이전까지는 Java 프로그래밍 언어에서 리터럴 문자열이 소스 파일의 줄에 걸쳐 있는 것을 허용하지 않으므로 여러 줄 문자열의 각 줄 끝에는
+연결 연산자를 사용해야 합니다. 예를 들어
String quote =
"Now is the time for all good " +
"men to come to the aid of their country.";연결 연산자 +를 사용하여 줄 사이를 연결하는 것은 print 문에서 매우 일반적입니다.
Java SE 15부터는 2차원 문자열 리터럴을 작성할 수 있습니다:
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
포맷 문자열 생성하기
형식이 지정된 숫자를 출력하기 위해 printf() 및 format() 메서드를 사용하는 것을 보았습니다. String 클래스에는 PrintStream 객체가 아닌 String 객체를 반환하는 동등한 클래스 메서드인 format()가 있습니다.
String의 정적 format() 메서드를 사용하면 일회성 인쇄 문과 달리 재사용할 수 있는 형식화된 문자열을 생성할 수 있습니다. 예를 들어
System.out.printf("The value of the float " +
"variable is %f, while " +
"the value of the " +
"integer variable is %d, " +
"and the string is %s",
floatVar, intVar, stringVar); 다음과 같이 쓸 수 있습니다.
String fs;
fs = String.format("The value of the float " +
"variable is %f, while " +
"the value of the " +
"integer variable is %d, " +
" and the string is %s",
floatVar, intVar, stringVar);
System.out.println(fs);
문자열을 숫자로 변환하기
프로그램에서 숫자 데이터가 문자열 객체(예: 사용자가 입력한 값)로 끝나는 경우가 종종 있습니다.
원시 숫자 타입을 감싸는 Number 서브클래스(Byte, Integer, Double, Float, Long, Short는 각각 문자열을 해당 타입의 객체로 변환하는 valueOf()라는 이름의 클래스 메서드를 제공합니다. 다음은 명령줄에서 두 개의 문자열을 가져와 숫자로 변환하고 값에 대해 산술 연산을 수행하는 ValueOfDemo의 예제입니다:
public class ValueOfDemo {
public static void main(String[] args) {
// this program requires two
// arguments on the command line
if (args.length == 2) {
// convert strings to numbers
float a = (Float.valueOf(args[0])).floatValue();
float b = (Float.valueOf(args[1])).floatValue();
// do some arithmetic
System.out.println("a + b = " +
(a + b));
System.out.println("a - b = " +
(a - b));
System.out.println("a * b = " +
(a * b));
System.out.println("a / b = " +
(a / b));
System.out.println("a % b = " +
(a % b));
} else {
System.out.println("This program " +
"requires two command-line arguments.");
}
}
}다음은 명령줄 인수에 4.5와 87.2를 사용할 때 프로그램의 출력입니다:
a + b = 91.7
a - b = -82.7
a * b = 392.4
a / b = 0.0516055
a % b = 4.5Note: 원시 숫자 타입을 래핑하는
Number서브클래스 각각은parseXXXX()메서드도 제공합니다. 예를 들어,parseFloat()는 문자열을 원시 숫자로 변환하는 데 사용할 수 있습니다. 객체 대신 원시 타입이 반환되므로parseFloat()메서드가valueOf()메서드보다 더 직접적입니다. 예를 들어ValueOfDemo프로그램에서 사용할 수 있습니다:
float a = Float.parseFloat(args[0]);
float b = Float.parseFloat(args[1]);
숫자를 문자열로 변환하기
값을 문자열 형식으로 작업해야 하기 때문에 숫자를 문자열로 변환해야 하는 경우가 있습니다. 숫자를 문자열로 변환하는 몇 가지 쉬운 방법이 있습니다:
int i;
// Concatenate "i" with an empty string; conversion is handled for you.
String s1 = "" + i;또는
// The valueOf class method.
String s2 = String.valueOf(i);각 Number 서브클래스에는 기본 타입을 문자열로 변환하는 클래스 메서드인 toString()가 포함되어 있습니다. 예를 들어
int i;
double d;
String s3 = Integer.toString(i);
String s4 = Double.toString(d); ToStringDemo 예제는 toString() 메서드를 사용하여 숫자를 문자열로 변환합니다. 그런 다음 프로그램은 몇 가지 문자열 메서드를 사용하여 소수점 앞뒤 자릿수를 계산합니다:
public class ToStringDemo {
public static void main(String[] args) {
double d = 858.48;
String s = Double.toString(d);
int dot = s.indexOf('.');
System.out.println(dot + " digits " +
"before decimal point.");
System.out.println( (s.length() - dot - 1) +
" digits after decimal point.");
}
}이 프로그램의 출력은 다음과 같습니다:
3 digits before decimal point.
2 digits after decimal point.
인덱스로 문자 및 하위 문자열 가져오기
String 클래스에는 문자열의 내용을 검사하고, 문자열 내의 문자 또는 하위 문자열을 찾고, 대소문자를 변경하는 등의 작업을 위한 다양한 메서드가 있습니다.
문자열 내 특정 인덱스에 있는 문자는 charAt() 접근자 메서드를 호출하여 가져올 수 있습니다. 첫 번째 문자의 인덱스는 0이고 마지막 문자의 인덱스는 length() - 1입니다. 예를 들어, 다음 코드는 문자열에서 인덱스 9에 있는 문자를 가져옵니다:
String anotherPalindrome = "Niagara. O roar again!";
char aChar = anotherPalindrome.charAt(9);인덱스는 0부터 시작하므로 다음 그림과 같이 인덱스 9의 문자는 ‘O’입니다:

문자열에서 문자 인덱스 찾기
문자열에서 연속된 문자를 두 개 이상 가져오려면 부분 문자열 메서드를 사용할 수 있습니다. 부분 문자열 메서드에는 두 가지 버전이 있습니다:
String substring(int beginIndex, int endIndex): 이 문자열의 부분 문자열인 새 문자열을 반환합니다. 부분 문자열은 지정된beginIndex에서 시작하여 인덱스endIndex - 1의 문자까지 확장됩니다.String substring(int beginIndex): 이 문자열의 부분 문자열인 새 문자열을 반환합니다. 정수 인수는 첫 번째 문자의 인덱스를 지정합니다. 여기서 반환된 부분 문자열은 원래 문자열의 끝 부분까지 확장됩니다.
다음 코드는 나이아가라 팔린드롬에서 인덱스 11부터 인덱스 15까지 확장되는 부분 문자열(단어 “roar”는 포함하지 않음)을 가져옵니다:
String anotherPalindrome = "Niagara. O roar again!";
String roar = anotherPalindrome.substring(11, 15); 
하위 문자열을 사용하여 문자열에서 문자 추출하기
문자열을 조작하는 다른 메서드
다음은 문자열을 조작하는 다른 String 메서드 몇 가지입니다:
String[] split(String regex)및String[] split(String regex, int limit): 문자열 인자(정규식이 포함된)에 지정된 일치 항목을 검색하고 그에 따라 이 문자열을 문자열 배열로 분할합니다. 선택적 정수 인수는 반환되는 배열의 최대 크기를 지정합니다. 정규 표현식은 “정규 표현식” 섹션에서 다룹니다.CharSequence subSequence(int startIndex, int endIndex):beginIndex인덱스에서endIndex - 1까지 구성된 새로운 문자 시퀀스를 반환합니다.String trim(): 선행 및 후행 공백이 제거된 이 문자열의 복사본을 반환합니다.String toLowerCase()및String toUpperCase(): 소문자 또는 대문자로 변환된 이 문자열의 복사본을 반환합니다. 변환이 필요하지 않은 경우 이 메서드는 원래 문자열을 반환합니다.
문자열에서 문자 및 하위 문자열 검색하기
다음은 문자열 내에서 문자 또는 하위 문자열을 찾는 다른 String 메서드입니다. String 클래스는 특정 문자 또는 하위 문자열의 문자열 내 위치를 반환하는 접근자 메서드를 제공합니다: indexOf() 및 lastIndexOf(). indexOf() 메서드는 문자열의 시작부터 앞으로 검색하고, lastIndexOf() 메서드는 문자열의 끝부터 뒤로 검색합니다. 문자 또는 하위 문자열을 찾을 수 없는 경우 indexOf() 및 lastIndexOf()는 -1을 반환합니다.
String 클래스는 문자열에 특정 문자 시퀀스가 포함된 경우 true를 반환하는 검색 메서드인 contains도 제공합니다. 문자열에 문자 시퀀스가 포함되어 있다는 것만 알고 싶지만 정확한 위치는 중요하지 않은 경우 이 메서드를 사용합니다.
검색 방법은 다음과 같습니다:
int indexOf(int ch)및int lastIndexOf(int ch): 지정된 문자의 첫 번째 (마지막) 발생의 인덱스를 반환합니다.int indexOf(int ch, int fromIndex)및int lastIndexOf(int ch, int fromIndex): 지정된 인덱스에서 앞으로 (뒤로) 검색하여 지정된 문자의 첫 번째 (마지막) 발생의 인덱스를 반환합니다.int indexOf(String str)및int lastIndexOf(String str): 지정된 부분 문자열의 첫 번째 (마지막) 발생의 인덱스를 반환합니다.int indexOf(String str, int fromIndex)및int lastIndexOf(String str, int fromIndex): 지정된 인덱스에서 정방향 (역방향)으로 검색하여 지정된 부분 문자열의 첫 번째 (마지막) 발생의 인덱스를 반환합니다.boolean contains(CharSequence s): 문자열에 지정된 문자 시퀀스가 포함되어 있으면true를 반환합니다.
Note:
CharSequence는String클래스에 의해 구현되는 인터페이스입니다. 따라서contains()메서드의 인수로 문자열을 사용할 수 있습니다.
문자열에 문자 및 하위 문자열 삽입하기
String 클래스에는 문자열에 문자나 하위 문자열을 삽입하는 메서드가 거의 없습니다. 일반적으로 이러한 메서드는 필요하지 않습니다: 문자열에서 제거한 하위 문자열을 삽입하려는 하위 문자열과 연결하여 새 문자열을 만들 수 있습니다.
그러나 String 클래스에는 발견된 문자 또는 하위 문자열을 대체하는 네 가지 메서드가 있습니다. 다음과 같습니다:
String replace(char oldChar, char newChar): 이 문자열에서oldChar의 모든 항목을newChar로 대체한 결과 새 문자열을 반환합니다.String replace(CharSequence target, CharSequence replacement): 리터럴 대상 시퀀스와 일치하는 이 문자열의 각 부분 문자열을 지정된 리터럴 대체 시퀀스로 바꿉니다.String replaceAll(String regex, String replacement): 주어진 정규식과 일치하는 이 문자열의 각 부분 문자열을 주어진 대체 항목으로 바꿉니다.String replaceFirst(String regex, String replacement): 주어진 정규식과 일치하는 이 문자열의 첫 번째 부분 문자열을 주어진 치환으로 바꿉니다.
실제로 작동하는 문자열 클래스
다음 Filename 클래스는 파일 이름의 다른 부분을 분리하기 위해 lastIndexOf() 및 substring()을 사용하는 방법을 보여줍니다.
참고: 다음
Filename클래스의 메서드는 오류 검사를 수행하지 않으며 인자에 전체 디렉토리 경로와 확장자가 있는 파일 이름이 포함되어 있다고 가정합니다. 이러한 메서드가 프로덕션 코드였다면 인수가 올바르게 구성되었는지 확인했을 것입니다.
public class Filename {
private String fullPath;
private char pathSeparator,
extensionSeparator;
public Filename(String str, char sep, char ext) {
fullPath = str;
pathSeparator = sep;
extensionSeparator = ext;
}
public String extension() {
int dot = fullPath.lastIndexOf(extensionSeparator);
return fullPath.substring(dot + 1);
}
// gets filename without extension
public String filename() {
int dot = fullPath.lastIndexOf(extensionSeparator);
int sep = fullPath.lastIndexOf(pathSeparator);
return fullPath.substring(sep + 1, dot);
}
public String path() {
int sep = fullPath.lastIndexOf(pathSeparator);
return fullPath.substring(0, sep);
}
}다음은 Filename 객체를 구성하고 모든 메서드를 호출하는 프로그램인 FilenameDemo입니다:
public class FilenameDemo {
public static void main(String[] args) {
final String FPATH = "/home/user/index.html";
Filename myHomePage = new Filename(FPATH, '/', '.');
System.out.println("Extension = " + myHomePage.extension());
System.out.println("Filename = " + myHomePage.filename());
System.out.println("Path = " + myHomePage.path());
}
}프로그램의 출력은 다음과 같습니다:
Extension = html
Filename = index
Path = /home/user다음 그림과 같이 확장 메서드는 lastIndexOf()를 사용하여 파일 이름에서 마침표(.)가 마지막으로 나오는 부분을 찾습니다. 그런 다음 lastIndexOf()의 반환값을 사용하여 파일 이름 확장자, 즉 마침표에서 문자열 끝까지의 부분 문자열을 추출합니다. 이 코드는 파일 이름에 마침표가 포함되어 있다고 가정합니다. 파일 이름에 마침표가 없는 경우 lastIndexOf()는 -1을 반환하고, 하위 문자열 메서드는 StringIndexOutOfBoundsException을 던집니다.
또한, 확장 메서드는 substring()의 인자로 점 + 1을 사용합니다. 마침표 문자(.)가 문자열의 마지막 문자인 경우 점 + 1은 문자열의 길이와 같으며, 이는 문자열에서 가장 큰 인덱스보다 하나 더 큽니다(인덱스는 0에서 시작하므로). 이 메서드는 문자열 길이와 같지만 그보다 크지 않은 인덱스를 허용하고 “문자열의 끝”을 의미하는 것으로 해석하기 때문에 substring()의 합법적인 인수가 됩니다.
문자열과 문자열의 일부 비교하기
String 클래스에는 문자열과 문자열의 일부를 비교하는 여러 메서드가 있습니다. 다음 표에는 이러한 메서드가 나열되어 있습니다.
boolean endsWith(String suffix)andboolean startsWith(String prefix): 이 문자열이 메서드의 인자로 지정된 부분 문자열로 끝나거나 시작하면true를 리턴합니다.boolean startsWith(String prefix, int offset): 문자열이 인덱스offset에서 시작하는 것으로 간주하고, 인자로 지정된 부분 문자열로 시작하면true를 반환합니다.int compareTo(String anotherString): 두 문자열을 사전적으로 비교합니다. 이 문자열이 인자보다 큰지(결과가 > 0), 같은지(결과가 = 0) 또는 작은지(결과가 < 0)를 나타내는 정수를 반환합니다.int compareToIgnoreCase(String str): 대소문자의 차이를 무시하고, 두 문자열을 사전적으로 비교합니다. 이 문자열이 인자보다 큰지(결과가 > 0), 같은지(결과가 = 0) 또는 작은지(결과가 < 0)를 나타내는 정수를 반환합니다.boolean equals(Object anObject): 인자가 이 객체와 동일한 문자 시퀀스를 나타내는String객체인 경우에만true를 반환합니다.boolean equalsIgnoreCase(String anotherString): 인자가 대소문자의 차이를 무시하고 이 객체와 동일한 문자 시퀀스를 나타내는String객체인 경우에만true를 리턴합니다.boolean regionMatches(int toffset, String other, int ooffset, int len): 이 문자열의 지정된 영역이String인자의 지정된 영역과 일치하는지 여부를 테스트합니다. 영역의 길이는len이며, 이 문자열의 경우toffset인덱스에서 시작하고 다른 문자열의 경우ooffset인덱스에서 시작합니다.boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len): 이 문자열의 지정된 영역이String인자의 지정된 영역과 일치하는지 여부를 테스트합니다. 영역의 길이는len이며, 이 문자열의 경우toffset인덱스에서 시작하고 다른 문자열의 경우ooffset인덱스에서 시작합니다. 부울 인수는 대/소문자를 무시할지 여부를 나타내며,true이면 문자를 비교할 때 대/소문자를 무시합니다.boolean matches(String regex): 이 문자열이 지정된 정규식과 일치하는지 여부를 테스트합니다. 정규 표현식은 “정규 표현식” 단원에서 설명합니다.
다음 프로그램인 RegionMatchesDemo는 regionMatches() 메서드를 사용하여 다른 문자열 내에서 문자열을 검색하는 프로그램입니다:
public class RegionMatchesDemo {
public static void main(String[] args) {
String searchMe = "Green Eggs and Ham";
String findMe = "Eggs";
int searchMeLength = searchMe.length();
int findMeLength = findMe.length();
boolean foundIt = false;
for (int i = 0;
i <= (searchMeLength - findMeLength);
i++) {
if (searchMe.regionMatches(i, findMe, 0, findMeLength)) {
foundIt = true;
System.out.println(searchMe.substring(i, i + findMeLength));
break;
}
}
if (!foundIt)
System.out.println("No match found.");
}
}이 프로그램의 출력은 Eggs입니다.
이 프로그램은 searchMe()가 참조하는 문자열을 한 번에 한 문자씩 단계적으로 살펴봅니다. 각 문자에 대해 프로그램은 regionMatches() 메서드를 호출하여 현재 문자로 시작하는 하위 문자열이 프로그램이 찾고 있는 문자열과 일치하는지 여부를 확인합니다.