열번 째 수업

정혅·2024년 2월 21일

더 조은 아카데미

목록 보기
15/76

문자열

문자열 변경

  1. 문자열은 변경이 불가능하다.

    • int처럼 값을 덮어쓰는것이 아니라, 해당 문자열의 새로운 객체를 만들어서 그 값의 주소를 참조하는 형식이 된다.

문자열 객체

  1. String으로 생겨난 객체 안에 똑같은 문자열을 생성한다면, 새로 객체를 생성하지 않고, 이전에 생성된 객체의 주소를 참조한다.
  2. 그러나 new 연산자를 사용한다면, 똑같은 문자열의 객체가 존재해도 새로운 객체가 생성된다.
    • 그러나 문자열 객체를 생성할 때는 메모리 효율 측면을 봤을 때 new보다 쌍따옴표를 이용한 객체 생성이 좋다.

문자열 객체들의 연결

class StringMethod
{
    public static void main(String[] args)
    {
        String str1="Smart";
        String str2=" and ";
        String str3="Simple";
        String str4=str1.concat(str2).concat(str3);
        //문자열 객체들을 합쳐서 새로운 객체의 주소값을 가지게되는것
        //concat을 이용해 메소드 체이닝 
        System.out.println(str4);    
        System.out.println("문자열 길이: "+str4.length());

        if(str1.compareTo(str3)<0)
            System.out.println("str1이 앞선다");
        else
            System.out.println("str3이 앞선다");
    }
}
  • str4는 Smart and Simple로 출력되게 된다.

문자열 api <> char - concat() / valueOf

concat() 문자 연결 : String만 받는다.

valueOf() 매개변수의 자료형이나, 개수가 달라도 String으로 반환 > 메소드 오버로딩 개념

class StringAdd
{
    public static void main(String[] args)
    {
        String str1="Lemon"+"ade"; //"Lemonade"
        String str2="Lemon"+'A'; //"Lemon".concat(String.valueOf('A')) 
        String str3="Lemon"+3; //"Lemon".concat(String.valueOf(3))
        String str4=1+"Lemon"+2; //총 생기는 문자열 객체 수는 5개.. 
        str4+='!';

        System.out.println(str1);        
        System.out.println(str2);        
        System.out.println(str3);        
        System.out.println(str4);
    }
}

String Builder

String 변경이 불가능한 문자열의 표현을 위한 클래스이지만, StringBuilder는 변경이 가능한 문자열의 표현을 위한 클래스들이다. > 문자열이라고 하지 x

특징

  • 문자열의 저장 및 변경을 위한 메모리 공간(이를 가리켜 '버퍼'라 한다)을 내부에 지닌다 > 공간의 크기가 자동으로 조절된다는 특징이 있다.

  • StringBuilder는 버퍼의 크기를 스스로 확장한다.
    @ public StringBuilder() // 16개의 문자 저장 버퍼 생성
    @ public StringBuilder(int capacity) // capacity개의 문자 저장 버퍼 생성
    @ public StringBuilder(String str) // str.length() + 16개의 문자 저장 버퍼 생성

    • 버퍼의 크기를 확장하는 작업은 많은 연산이 요구되는 작업ㅇ므로 가급적이면 필요로 하는 버퍼의 크기를 미리 할당하는 것이 성능에 도움이 된다.

  • append() >StringBuilder 의 객체 주소를 반환

  • aaa.aa.a > 메소드 체이닝의 형태 > 객체의 주소값을 가지고 있어야

class BuilderString
{
    public static void main(String[] args)
    {
        StringBuilder strBuf=new StringBuilder("AB");
        strBuf.append(25);
        strBuf.append('Y').append(true);
        //*.*.*이렇게 .. 의 형태가 메소드 체이닝이라 하는데 객체의 주소값이 들어있어야 가능하다.
        System.out.println(strBuf);        

        strBuf.insert(2, false);//AB false 25Ytrue 가 된 형태, 2번째 자리에 false 삽입
        strBuf.insert(strBuf.length(), 'Z');
        System.out.println(strBuf);
    }
}

메소드 체이닝

  • 반환되는 값이 본인의주소값이 아니면, 에러가 난다. (return this 활용)

퀴즈 - StringBuilder > 역순, 삭제

  1. String str1 = "ABCDEFGHIJKLMN"; 역순으로 출력

    reverse();이용 : 역순으로 출력 > StringBuilder 로 반환

    toString >String으로 반환해서

  2. String str2 = "990208-1012752" 이 문자열을 활용하여 중간에 삽입된 -를 삭제한

  3. String 인스턴스를 생성.

내가 한것 - 1번은 정답

class BuilderMain{
    public static void main(String[]args){
        String str1 = "ABCDEFGHIFKLMN";
        StringBuilder sb = new StringBuilder(str1); //builder객체로 따로 생성
        System.out.println(sb.reverse().toString());

        String str2 = "990208-1012752";
        StringBuilder ab = new StringBuilder(str2);
        System.out.println(ab.deleteCharAt(6));

    }
}    //정답이랑 비교 <> String으로 반환되게끔 하지 x
    //원하는 문자가 없을 때의 가정을 하지 x
  • 처음에 위에서 했던 메소드 체이닝 때문에 클래스를 따로 생성해서 불러와야하나 싶었는데, 그게 아니였다.

  • java.lang.StringBuilder의 메소드를 사용하고 있기 때문에 String객체에서 끝나는것이 아니라 StringBuilder객체를 새로 생성해서 메소드를 사용해 주어야한다.

정답 - 틀린 2번만

String str2 = "990208-1012752";
idx = sb2.indexOf("-");
if(idx != -1) //원하는 문자가 없으면 -1을 반환
StringBuilder ab = new StringBuilder(str2);
System.out.println(ab.deleteCharAt(idx).toString()); //다시 String으로 반환
  • indexOf..? 띠용 잘 이해 x 스터디때 물어보기

String Buffer

StringBuild와 마찬가지로 변경이 가능한 문자열의 표현


생성자 오버로딩

class Person
{
    private int perID;
    private int milID;
    private int birthYear;
    private int birthMonth;
    private int birthDay;

    public Person(int perID, int milID, int bYear, int bMonth, int bDay)
    {//person 생성자끼리 서로 호출해서 초기
        this.perID=perID;
        this.milID=milID;
        birthYear=bYear;
        birthMonth=bMonth;
        birthDay=bDay;
    }
    public Person(int pID, int bYear, int bMonth, int bDay)
    {
        this(pID, 0, bYear, bMonth, bDay);
    }
    public void showInfo()
    {
        System.out.println("민번: "+perID);
        System.out.println(
                "생년월일: "+birthYear+"/"+birthMonth+"/"+birthDay);
        if(milID!=0)
            System.out.println("군번: "+milID+'\n');
        else
            System.out.println("군과 관계 없음 \n");
    }
}

class CstOverloading
{
    public static void main(String[] args)
    {
        Person man=new Person(950123, 880102, 1995, 12, 3);
        Person woman=new Person(990117, 1999, 11, 7);
        man.showInfo();
        woman.showInfo();
    }
}
  • 생성자 : 객체를 생성할 때 단 한번 생성되는 특수한 메소드로, 다른 메소드내에서 호출이 불가능한데, 다른 메소드의 생성자 안에서는 호출이 가능하다.
    • 생성자 내에서 다른 생성자 호출 가능

퀴즈 - 자바 개념풀이 오답

[ 6번 ]

  • 논리 연산자 and가 or보다 우선순위 더 높다 > % 이용해서

  • 이는 윤년 구하는 공식이다.


[8번]

  • equals()메소드 > 문자열의 값을 비교할 때(대소문자 구분)

    str.equals("yes") > 두 문자열이 같으면 true 다르면 false를 반환한다.

    String str1 = "yes"
    String str2 = "yes"
    syso (str1.equals(str2)); //참조하는 객체의 주소가 같은지를 비교
    System.out.print(str1 == str2); //이것과 혼동 x > 문자열 값을 비교 
    • 동일한 문자열이면 객체를 새로 생성하지 않고, 이전에 생성했던 객체를 참조하므로 equals()메소드는 동일한 주소값을 가지고 있는지 비교하는 메소드다.
  • equalsIgnoreCase() 는 대소문자 상관 없이 비교한다


내가 작성한 식

class T3{
    public static void main(String[]args){
        int num1 = 0;
        int num2 = 0;
        int sum = 0;
        for(; num1 <= 10; num1++){

            for(; num2 <= 10; num2++){
                sum += num2;
            }
            System.out.print("현재 더해진 합 : " + sum + "\n");
        }
        System.out.print("총 합 : " + sum);
    }
}
  • 이중 for문을 사용하는줄 알았다. > 논리적으로 생각해보면 값을 담을 변수를 하나 더 만들어 더해주면 되었던건데..

  • for문에 증감조건이 , (컴마) 로 되어있으면 두개 다 수행한다.

  • s = -s 코드를 통해 짝수번 수행할 때 음수, 양수로 번갈아 가며 변환해준다.

내가 작성한 식

class T4{
    public static void main(String[]args){
        int num1 = 0;
        int sum = 0;
        int cnt = 0;

        for(; sum <= 100; num1++){

            if(num1 % 2 == 0){

                cnt++;
                sum -= num1;
                continue;
            }    
            cnt++;
            sum += num1;
        }    
        System.out.print(cnt + " 번 더해야 총합이 " + sum + "이 됩니다.");    
    }
}

  • 안쪽 while문이 종료되면 중괄호 이후에 있는 구문이 수행되므로 저곳에 출력구문 넣고, while문이므로 안쪽 while문이 종료되면, 다시 j를 초기화 시켜야한다.

  • AB BA 전에 했던것과 유사한


  • int보다 작은 자료형은 연산을 할때 int로 자동 형변환 되기 때문에, '1' - '0' 이 되는데, 이는 int니까 아스키코드로 49 - 48 의 계산식이 된다.

  • 그러므로 '0'을 빼줌으로써 1,2,3,4,5가 차례로 출력된다.

char ch = '0';
syso ((int)ch); 

이렇게 출력하면 해당 아스키코드 값을 확인할 수 있다. > 앵간하면 암기

내가 푼 코드

class T9{//9번
    public static void main(String[]args){
        String str = "12345";
        int sum = 0;

        for(int i = 0; i < str.length(); i++){
            sum += str.charAt(i);
        }
        System.out.println("sum=" + sum);
    }
}    
  • int로 변환하면 아스키로 변환되어서 저장되는데 그 생각을 못해부러쓰..

  • 나머지 연산을 이용해 제일 마지막값을 가져올 수 있다.

  • 마지막 값을 가지고 왔으니 10으로 나누어서 가져온 마지막 값을 잘라낸다.


  • 너무 복잡하게 생각하지 말고, 세번째 수를 출력해준 뒤, 한칸 씩 땡겨서 다시 더해주면 되므로, num1 = num2가 되고, num2 = num3이 되고 기존 num3은 num1 + num2가 되므로 피보나치 수열이 가능해진다.

  • 보면 9행 3열이니 바깥for문을 9, 안쪽 for문을 3으로 하고, 안쪽 for문안에 숫자 출력하고 \t한후 바깥쪽 for문에 개행시키면 된다.

내가 푼 문제

class T12{
    public static void main(String[]args){
        int dan = 0, num = 0;

        for(num = 1; num < 4; num++){
            for(dan = 2; dan < 10; dan++){
                System.out.print(dan + " * " + num + " = " + dan * num + "\t");
            }
        }System.out.println();
    }
}
  • 가로로 나열 시키긴 했는데, 단이 나누어서 개행되지않아 저기서 stop했다

  • 애초에 단 수가 중요한게아니라 9행 3열인데, 그것을 생각하지 않은 나의 잘못..

다른 방법

public T12{
    public static void main(String[]args){
        int num1 =1, num2 = 1;
        for(int i = 0; i < 9; i++){

        num2 = 1 % 3 + 1;
        for(int j = 0; j < 3; j++){
            num1 = i / 3 * 3 + 2 + j;
            if(num1 <= 9) break;
            System.out.print(num1 + "*" + num + " = " + num1 * num2 + "\t");
        }
        System.out.println();
        if((i + 1 ) % 3 == 0) System.out.println();
    }
}    //해설과 다른 풀이 

내가 푼 문제 - 정답을 맞췄지만 게시

class T13{
    public static void main(String[]args){

        String value = "12o34"; //영어 o
        char ch;
        boolean isNumber = true;

        for(int i = 0; i < value.length(); i++){

            ch = value.charAt(i);

            if('0' <= ch && ch<= '9'){//영어o는 0보다 크지만 9보다 작다.
                isNumber = true;
            }else{ isNumber = false; break;}

        }
        if(isNumber){
            System.out.println(value + "는 숫자입니다.");
        }else
            System.out.println(value + "는 숫자가 아닙니다.");
    }
}

  • tmp % 10 > 마지막 값을 구하는 식

  • tmp / 10 > 구한 마지막 값을 잘라내는 식

  • 마지막값을 result에 차례로 반환시켜 저장 후 마지막에 if문을 이용해 회문수인지 아닌지 판별시킨다.

0개의 댓글