1. StringTokenizer클래스

이제 문자열 작업과 관련된 몇 가지 일반적인 시나리오가 있습니다. 문자열을 여러 부분으로 어떻게 분할합니까? 이를 수행하는 방법에는 여러 가지가 있습니다.

split()방법

문자열을 여러 부분으로 분할하는 첫 번째 방법은 이 split()방법을 사용하는 것입니다. 특수 구분 문자열을 정의하는 정규식을 인수로 전달해야 합니다. Java Multithreading 퀘스트 에서 정규 표현식이 무엇인지 배우게 됩니다 .

예:

암호 결과
String str = "Good news everyone!";
String[] strings = str.split("ne");
System.out.println(Arrays.toString(strings));
결과는 세 문자열의 배열입니다.
["Good ", "ws everyo", "!"]

간단하지만 때로는 이 접근 방식이 과도합니다. 구분 기호(예: 공백, 개행 문자, 탭, 마침표)가 많으면 다소 복잡한 정규식을 구성해야 합니다. 읽기 어려우므로 수정하기 어렵습니다.

StringTokenizer수업

Java에는 전체 작업이 문자열을 하위 문자열로 분할하는 특수 클래스가 있습니다.

이 클래스는 정규식을 사용하지 않습니다. 대신 구분 기호로 구성된 문자열을 전달하기만 하면 됩니다. 이 접근 방식의 장점은 전체 문자열을 한 번에 여러 조각으로 나누지 않고 처음부터 끝까지 한 번에 한 단계씩 이동한다는 것입니다.

이 클래스에는 생성자와 두 가지 중요한 메서드가 있습니다. 우리는 부분으로 분할한 문자열과 일련의 구분 문자로 구성된 문자열을 생성자에 전달합니다.

행동 양식 설명
String nextToken()
다음 하위 문자열을 반환합니다.
boolean hasMoreTokens()
하위 문자열이 더 있는지 확인합니다.

이 클래스는 어떻게든 스캐너 클래스를 연상시키며 메서드도 nextLine()있습니다 hasNextLine().

StringTokenizer다음 명령을 사용하여 개체를 만들 수 있습니다 .

StringTokenizer name = new StringTokenizer(string, delimiters);

string부분으로 나눌 문자열은 어디에 있습니까? And delimiters는 문자열이며 그 안의 각 문자는 구분 기호로 처리됩니다. 예:

암호 콘솔 출력
String str = "Good news everyone!";

StringTokenizer tokenizer = new StringTokenizer(str,"ne");
while (tokenizer.hasMoreTokens())
{
   String token = tokenizer.nextToken();
   System.out.println(token);
}
Good 
ws 
v
ryo
!

두 번째 문자열로 생성자에 전달된 문자열의 각 문자는 StringTokenizer구분 기호로 간주됩니다.



2. String.format()메소드 및 StringFormatter클래스

String 클래스의 또 다른 흥미로운 방법은 format().

데이터를 저장하는 다양한 변수가 있다고 가정해 보겠습니다. 한 줄로 화면에 어떻게 표시합니까? 예를 들어 일부 데이터(왼쪽 열)와 원하는 출력(오른쪽 열)이 있습니다.

암호 콘솔 출력
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;
User = {name: Amigo, age: 12 years, friend: Diego, weight: 200 kg.}

코드는 다음과 같을 것입니다.

프로그램 코드
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;

System.out.println("User = {name: " + name + ", age:" + age + " years, friend: " + friend+", weight: " + weight + " kg.}");

이러한 코드는 가독성이 좋지 않습니다. 변수 이름이 더 길면 코드가 훨씬 더 어려워집니다.

프로그램 코드
class User {
    ......
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public List<String> getFriends() {
        return friends;
    }

    public ExtraInformation getExtraInformation() {
        return extraInformation;
    }
}

User user = new User();

System.out.println("User = {name: " + user.getName() + ", age:" + user.getAge() + " years, friend: " + user.getFriends().get(0) + ", weight: " + user.getExtraInformation().getWeight() + " kg.}");

잘 읽히지 않습니까?

하지만 이는 실제 프로그램에서 흔히 볼 수 있는 상황이므로 이 코드를 보다 간단하고 간결하게 작성할 수 있는 방법에 대해 알려드리고자 합니다.

String.format

String 클래스에는 정적 format()메서드가 있습니다. 이를 통해 문자열을 데이터와 결합하기 위한 패턴을 지정할 수 있습니다. 명령의 일반적인 모양은 다음과 같습니다.

String name = String.format(pattern, parameters);

예:

암호 결과
String.format("Age=%d, Name=%s", age, name);
Age=12, Name=Amigo
String.format("Width=%d, Height=%d", width, height);
Width=20, Height=10
String.format("Fullname=%s", name);
Fullname=Diego

메서드 의 첫 번째 매개변수 는 데이터를 삽입해야 하는 위치에 형식 지정자(예: 및 ) format()라고 하는 특수 문자와 함께 원하는 모든 텍스트를 포함하는 형식 문자열입니다 .%d%s

format()메서드는 이들 %s%d형식 지정자를 매개 변수 목록에서 형식 문자열 뒤에 오는 매개 변수로 바꿉니다. 문자열을 삽입하려면 %s. 숫자를 삽입하려는 경우 형식 지정자는 입니다 %d. 예:

암호 결과
String s = String.format("a=%d, b=%d, c=%d", 1, 4, 3);
s동일하다"a=1, b=4, c=3"

다음은 형식 문자열 내에서 사용할 수 있는 형식 지정자의 짧은 목록입니다.

지정자 의미
%s
String
%d
정수: byte, short, int,long
%f
실수: float,double
%b
boolean
%c
char
%t
Date
%%
%성격

이러한 지정자는 데이터 유형을 나타내지만 데이터의 순서를 나타내는 지정자도 있습니다. 번호로 인수를 가져오려면(번호는 1부터 시작) " " 대신 " " 를 작성해야 합니다 . 예:%1$d%d

암호 결과
String s = String.format("a=%3$d, b=%2$d, c=%d", 11, 12, 13);
s동일하다"a=13, b=12, c=11"

%3$d세 번째 인수, %2$d두 번째 인수, %d첫 번째 인수를 가져옵니다. 및 형식 지정자는 또는와 같은 지정자와 상관없이 인수를 참조합니다 %s.%d%3$d%2$s



3. 스트링 풀

StringPool문자열 리터럴로 코드에 지정된 모든 문자열은 프로그램이 실행되는 동안 이라는 메모리 영역에 저장됩니다 . StringPool문자열을 저장하기 위한 특수 배열입니다. 그 목적은 문자열 저장을 최적화하는 것입니다.

첫째, 코드에 지정된 문자열은 어딘가에 저장되어야 합니다. 코드는 명령으로 구성되지만 데이터(특히 큰 문자열)는 코드와 별도로 메모리에 저장해야 합니다. 문자열 개체에 대한 참조만 코드에 나타납니다.

둘째, 모든 동일한 문자열 리터럴은 메모리에 한 번만 저장되어야 합니다. 그리고 그것이 작동하는 방식입니다. 클래스 코드가 Java 시스템에 의해 로드되면 모든 문자열 리터럴이 StringPool아직 없는 경우 에 추가됩니다. 이미 있는 경우 StringPool.

따라서 코드의 여러 변수에 동일한 리터럴을 할당하면 String이러한 변수에 동일한 참조가 포함됩니다. 리터럴은 한 번만 추가됩니다 StringPool. 다른 모든 경우에 코드는 에 이미 로드된 문자열에 대한 참조를 가져옵니다 StringPool.

작동 방식은 대략 다음과 같습니다.

암호 StringPool 작업
String a = "Hello";
String b = "Hello";
String c = "Bye";
String[] pool = {"Hello", "Bye"};
a = pool[0];
b = pool[0];
c = pool[1];

a이것이 및 b변수가 동일한 참조를 저장하는 이유입니다 .

intern()방법

그리고 가장 좋은 점은 프로그래밍 방식으로 모든 문자열을 StringPool. 이렇게 하려면 String변수의 intern()메서드를 호출하기만 하면 됩니다.

메서드 는 아직 없는 경우 intern()문자열을 에 추가하고 의 문자열에 대한 참조를 반환합니다 .StringPoolStringPool

StringPool메서드를 사용 하여 두 개의 동일한 문자열이 추가되면 intern()메서드는 동일한 참조를 반환합니다. 참조로 문자열을 비교하는 데 사용할 수 있습니다. 예:

암호 메모
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b);


false
String a = new String("Hello");
String b = new String("Hello");

String t1 = a.intern();
String t2 = b.intern();
System.out.println(a == b);
System.out.println(t1 == t2);





false
true

이 방법을 자주 사용하지 않을 것 같지만 사람들은 인터뷰에서 이 방법에 대해 묻는 것을 좋아합니다 . 따라서 모르는 것보다 아는 것이 좋습니다.