Loading...

JAVA / / 2022. 1. 20. 12:00

자바 24강. String

반응형

 

은행의 A 컴퓨터와 홍길동의 B 컴퓨터가 통신을 할 것이다.

 

통신을 할 때 너무 길게 보내면 데이터가 무거워진다.

자연어 상태로 보내게 되면 컴퓨터는 이해할 수 없다.

 

컴퓨터가 이해하기 쉬운 데이터로 분석하는 파싱을 해주어야 한다.

 

경량 데이터를 보내려면 프로토콜을 만들어 경량화를 해두어야 한다.

자연어로 보내면 파싱이 안되기 때문이다.

 

자연어가 아닌 프로토콜을 지킨 상태로 보내야 파싱 할 수 있다.

누가 봐도 이해하기 쉽게 보내야 한다.

 

송신자 : 계좌번호 : 수신자 : 계좌번호 : 금액이라는 프로토콜을 정했고

홍길동은 계좌이체를 하기 위해 프로토콜에 맞추어

홍길동 : 10333377 : 장보고 : 1123333557 : 5000이라고 요청을 했다.

 

Byte Stream으로 들어오는 통신은 모두 문자열로 들어온다.

이 문자열을 ":" 기호를 기준으로 문자열 클래스 String의 메서드인

split( )을 이용해 파싱 해준다.

 

파싱 된 데이터들을 계좌이체내역 클래스에 하나씩 저장해준다.

다양한 자료형을 담을 수 있는 유일한 자료형이 커스텀 자료형, 즉 클래스이기 때문이다.

 

계좌이체내역의 생성자에 값을 받아와 저장하게 되는 것이다.

 

계좌이체내역 클래스의 money 변수에는 입금할 금액이 들어가는데,

우리는 문자열로 값을 받아서 int형 변수에 들어갈 수 없다.

 

이때 문자를 숫자로 바꾸기 위해

Integer 클래스의 parseInt( ) 메서드를 사용해주어야 한다.

 

int age = Integer.parseInt("5000");

이라고 하면 age에는 정수 5000이 저장되는 것이다.

 

그러면 숫자를 문자로 바꾸는 것은 어떻게 할까?

간단하다.

String num = 5000 + "";

결합 연산자를 이용하면 된다.

 

키:밸류 데이터를 받을 수 있는 타입이

클래스 타입(커스텀)

 


잠깐!

 

String을 쓴다는 것은 누가 만들어놓은 블랙박스,

즉 라이브러리를 사용한다는 것이다.

이 라이브러리가 내 패키지 안에 있는 게 아닌데 왜 import를 안 하고 사용했을까?

 

자바에는 기본 내장 객체가 있다

 

기본 내장 객체에는 수천, 수만 개의 메서드가 있는데

개발자들이 특히나 많이 사용하는 메서드가 있다.

 

String, Math, System과 같이 자주 사용하는 것들은

내장 객체라고 이름을 짓고 import 하지 않아도

사용할 수 있게 자바가 만들어준 것이다.

 

이 내장 객체들을 모두 외워야 할까?

사용했을 때 import를 안 해도 사용이 가능하다면

아, 내장 객체이구나! 하고 사용하면 된다.

 

블랙박스, 라이브러리는 내부 구조를 알 필요 없이 호출만 해서

어떤 값이 리턴되는지만 알고 사용하면 되지만

String은 구조를 알아두는 게 좋다.

 

String은 맨 앞글자가 대문자이다.

클래스라는 말인 것이다.

근데 우리는 String을 사용하면서 new를 안 쓰고도

메모리에 띄워져서 사용이 가능했다.

왜일까?

 

자바에서 String은 자주 사용하는 클래스니까

선언하고 초기화만 해주면 사용 가능하게 해 줄게! 한 것이다.

 

우리가 String s1 = "안녕";이라고 사용했던 것이

실제로는 new 되어 heap에 들어갔다.

 

String s2 = new String("안녕"); 이 원형인 것이다.

 

String s1 = "안녕";
String s2 = new String("안녕");
String s3 = new String("안녕");
String s4 = "안녕";

s3 = "하하";
s4 = "반가워";
s4 = s4 + "하하"

String을 new 해서 사용하는 것과 그냥 초기화하는 String은 차이가 있다.

 

new를 사용해서 heap 메모리에 띄운 s2와 s3은 그냥 heap 공간에 할당된다.

그냥 초기화 한 s1과 s4는 String Constant Pool 공간에 할당된다.

 

근데 Pool을 보고 어디서 많이 보던 것 같은 느낌이 들어야 한다!

바로 Pooling 기법이다.

pooling 기법은 메모리를 공유하는 기법이었다.

 

String 타입의 변수가 같은 값을 가지고 있다면

그 메모리 공간을 공유하겠다는 의미인 것이다.

 

s1과 s4가 "안녕"이라는 똑같은 값을 가지고 있으므로

s1과 s4에는 동일한 공간을 가리키는 동일한 주소 값이 저장된다.

 

String constant pool에 저장되어 있는 데이터의 값을 수정하면

저장되어 있는 데이터가 변하는 게 아니라 새로운 공간에 할당되게 된다.

 

하지만 new로 heap에 띄운 s2와 s3는

데이터를 새로운 공간에 다시 할당하는 것이 아닌

같은 공간에 내용이 바뀌게 된다.

 

// 같은 공간, 같은 주소
String a = "물";
String b = "물";

// 다른 공간, 다른 주소
String k = "별";
String z = new String("별");

 


http://www.dreamy.pe.kr/zbxe/CodeClip/3766960

 

JAVA String 클래스 메소드 정리

JAVA 2015.02.05 15:41 조회 수 75258 댓글 1 ? 단축키 Prev이전 문서 Next다음 문서 가 + - Up Down Print ? 단축키 Prev이전 문서 Next다음 문서 가 + - Up Down Print startWith: 문자열이 지정한 문자로 시작하는지 판단

www.dreamy.pe.kr

String 클래스의 메서드는 많이 사용하게 될 것이다.

한 번씩 예제도 따라 하면서 익숙해지자.

 

우리는 이제 아까 봤던 파싱 예제를 연습해볼 것이다.

 

 

Scanner scan = new Scanner(System.in);  // 1. scaaner로 문자열 받기

	String inform = scan.nextLine();

    String[] tokens = inform.split("-");    // 2. -로 split

    for (int i = 0; i < tokens.length; i++) {
    	System.out.println(tokens[i]);
    }

Scanner로 문자열을 받아서 "-"로 split( )까지 한 상태이다.

첫 데이터가 A01인지 확인해야 하는데

if("A01" == tokens[0] {

}

 

"A01"과 토큰의 0번지가 비교가 될까?

 

==은 값이 아닌 주소를 비교하는 것이다.

문자열 값 자체만으로 비교할 때는

String의 메서드인 equals( )를 사용해야 한다.

 

근데 문제를 보니 성별을 char 클래스로 받아야 한다.

char 자료형은 자바의 기본 자료형으로 2Byte 크기를 확보하는데

딱! 2Byte만 담을 수 있다.

그리고 문자열과 다르게 홑 따옴표로 글자를 담는다.

 

char ch = '가';

 

char와 배열을 더하면 문자열도 받을 수 있다.char [] s1 = new char [5];

 

char 타입의 배열을 선언할 때 배열의 크기를 얼마만큼 받아야 할까?

냅다 크기를 크게 잡으면 데이터의 낭비가 심할 것이고,

적게 잡으면 놓치는 데이터가 생길 것이다.

 

그렇기 때문에 char 배열

고정 길이의 문자열을 받을 때 사용한다.

 

주민등록번호와 같이

길이를 알고 있고, 변하지 않을 때 char 배열을 사용하면 된다.

 

String은 가변 길이의 데이터를 받을 때 사용하고,

char는 고정길이의 데이터를 받을 때 사용한다.

 

String 타입으로 "가나다"를 받으면 6Byte 공간을 확보하는데

"가"로 값이 바뀌면 2Byte 공간으로 줄어든다.

하지만 char 타입으로 "가나다"를 받으면 6Byte를 확보했다가

"가"로 값이 바뀌어도 6Byte 공간을 가지고 있다.

 

이것이 String과 char의 차이이다.

 

고정 길이일 때 String을 사용하는 것은 상관없지만,

가변 길이인데 char 배열을 쓰고 메모리를 많이 잡아놓아서는 안된다.

 

package stringex;

import java.util.Scanner;

class User {
    private String name;
    private String tel;
    private char gender;
    private int age;

    public User(String name, String tel, char gender, int age) {
        this.name = name;
        this.tel = tel;
        this.gender = gender;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getTel() {
        return tel;
    }
    public void setTel(String tel) {
        this.tel = tel;
    }
    public char getGender() {
        return gender;
    }
    public void setGender(char gender) {
        this.gender = gender;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

public class StringEx04 {
    public static void main(String[] args) {
        // System.in = 키보드 연결, System.out = 모니터 연결
        Scanner sc = new Scanner(System.in);
        // int num = sc.nextInt(); // "안녕" -> 런타임오류 numberformat exception
        
        // A01-이름:홍길동-전화번호:0102222-성별:남-나이: 20
        // String data = sc.nextLine();
        String data = "A01-이름:홍길동-전화번호:0102222-성별:남-나이: 20";

        String[] tokens = data.split("-");

        if(tokens[0].equals("A01")) {
            // 1. 이름:홍길동을 ":"으로 구분해서 홍길동을 찾자
            String name = tokens[1].split(":")[1];

            // 2. 전화번호:0102222를 ":"으로 구분해서 0102222를 찾자
            // 전화번호는 0으로 시작하니까 문자열로 받기
            // int로 받으면 102222로 바뀌게됨
            String tel = tokens[2].split(":")[1];

            // 3. 성별:남을 ":"으로 구분해서 남을 찾자
            String genderTemp = tokens[3].split(":")[1];

            // 4. 나이:20을 ":"으로 구분해서 20을 찾자
            String ageTemp = tokens[4].split(":")[1];

            // 5. char로 담고, int로 담고 하는 형변환하기
            // char gender = (char)genderTemp;
            // 명시적 형변환은 기본 자료형일때만 가능
            // String은 기본 자료형이 아니기때문에 오류발생
            // index는 항상 0부터 시작
            char gender = genderTemp.charAt(0);
            // 문자열의 공백 없애주는 String의 메서드 trim()
            int age = Integer.parseInt(ageTemp.trim());

            // 6. 클래스로 옮겨담기
            User user = new User(name, tel, gender, age); // 순서중요, 타입이 다르니까
            // 클래스의 이름을 모두 소문자(파스칼 지키기)로 바꿔 변수이름을 지정하는것이 규칙
            System.out.println("----");
        }else {
            System.out.println("프로그램 종료");
        }
    }
}

 

 

 

 

 

 

 

[출처]

 

https://cafe.naver.com/metacoding

 

메타코딩 : 네이버 카페

코린이들의 궁금증

cafe.naver.com

 

메타 코딩 유튜브

https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9

 

메타코딩

문의사항 : getinthere@naver.com 인스타그램 : https://www.instagram.com/meta4pm 깃헙 : https://github.com/codingspecialist 유료강좌 : https://www.easyupclass.com

www.youtube.com

 

반응형