Java

2.7 자동타입 변환

타입들이 공간이 다른데 서로 값을 옮겨담고 싶을때
1 -> 2 -> 4 -> 8 작은것을 큰공간으로 옮기는것은 당연히 될 것 같다.
거꾸로 옮겨담기 가능한가? 옮겨담을때 어떤문제가 발생하느냐

큰 범위 = 자동범위 타입 문제 없이 자동으로 타입변환된다.
컴파일러가 알아서 잡아준다.

정수 타입간에 작은 타입 -> 큰타입 : 자동 형변환
정수에서 실수로 : 자동형변환
문자char타입도 int나 long으로 자동형변환가능하다.

int i1; //4bytes
long l1; //8bytes
i1 = 100;
l1 = i1; //문제 없음

float f1; //4bytes
double d1; //8bytes
f1 = 3.14f;
d1 = f1; //문제 없음

int i2;
double d2;
i2 = 999999;
d2 = i2; //정수에서 실수로 자동 형변환

long l2;
l2 = 99999999999L;
d2 = l2; //정수에서 실수로 자동 형변환
float f2; //4bytes
f2 = l2; //변환 가능하지만 근사값으로 됨 주의!

char c3 = '가'; //2bytes 
int i3 = c3;// 자동형변환 (2bytes->4bytes)
long l3 = c3;// 자동형변환 (2bytes->8bytes)

2.8 강제타입변환

큰 허용 범위 타입은 작은 허용범위 타입으로 자동타입 변환할 수없다.
그렇지만 작은 단위로 쪼개서 한조각만 작은 그릇에 넣는것은 가능하다.

2.8.1 정수끼리, 실수끼리

큰타입 -> 작은타입 : 강제 형 변환(casting)필요하다.

int i1;
long l1;

l1 = 30;
i1 = (int) l1; // 강제 형 변환(casting 연산)
    //int로 표현이 가능하더라도 bytes수가 달라서 오류가 발생한다.

  l1 = 3000000000L;
  i1 = (int) l1;
  System.out.println(l1); //3000000000
  System.out.println(i1); //-1294967296

short s1 = 200; //2진수 0000 0000 1100 1000
byte b1 = (byte) s1; 
System.out.println(s1); //200
System.out.println(b1); //-56 앞을 잃어버리고 1100 1000

범위를 넘치는 값을 넣으면 오버플로우되서 표현된다.

2.8.2 실수 -> 정수 : 강제 형변환(casting)

double d2
int i2;

d2 = 3.14;
i2 = (int) d2; //강제형변환 소수점 아래 버려짐.
System.out.println(d2); //3.14
System.out.println(i2); //3

2.9 연산식에서 자동타입변환

의식하지 않아도 자동으로 바뀌는 경우가 있다.
연산 중 자동 형 변환된다.

byte b1 = 30;
byte b2 = 10;

// byte short int의 연산결과는 int
// byte b3 = b1 + b2;
int i3 = b1 + b2;
byte b4 = (byte) (b1 + b2);

byte b5 = 30 + 10; //리터럴은 그냥 그대로 되서 됨

정수간의 연산에서 long이 포함된 연산의 결과는 long이다.

long l6 = 30;
long l7 = 10;
// int i6 = l6 + l7; 불가능
long l8 = l6 + l7;

int i9 = 20;
// int i10 = i9 + l7; 불가능
long l10 = i9 + l7;

int i10 = (int) (i9 + l7); //굳이 담고싶다면 강제 형변환

!!!확인문제!!! 2 3 4 5 6 7
char는 빈 문자열이라는것이 존재하지 않는다.
float var4 = 10; int가 자동형변환되서 가능하다.

2.10 변수 사용 범위(scope)

선언된 블럭 안에서만 사용 가능하다. {}가 코드블럭 역할을 한다.

public class C13Scope {
    public static void main(String[] args) {
        int v1 = 3;

        if (true) {
            System.out.println(v1); // 사용가능

            int v2 = 5;

            System.out.println(v2); // 사용가능
        }
        //System.out.println(v2); // 사용불가능
    }
}

2.11 String 변환

  String s1 = "hello";
  String s2 = "h";
  //char c1 = (char) s2; //참조타입과 기본타입간 형변환 안됨
  String s3 = "";

하지만 문자열을 기본타입으로 형변환 하고 싶은 경우가 생긴다. 이럴때는 자바 API가 제공하는 메소드를 사용해야한다.

public class C14String {
    public static void main(String[] args) {
        // 문자열 -> 기본타입
        String str1 = "300";
        int i1 = Integer.parseInt(str1);
        System.out.println(i1); // 300

        String str2 = "90000000000000000";
        long l2 = Long.parseLong(str2);
        System.out.println(l2); // 9~0

        String str3 = "3.14";
        double d3 = Double.parseDouble(str3);
        System.out.println(d3); // 3.14

        String str4 = "9.99";
        float f4 = Float.parseFloat(str4);
        System.out.println(f4); // 9.99

        String str5 = "true";
        boolean b5 = Boolean.parseBoolean(str5);
        System.out.println(b5); // true
    }
}

각 타입의 Class 안에 있는 메소드를 사용하는 것이다.

반대로 기본타입을 문자열로 바꿀 수도 있다.
String 객체의 valueOf() 메소드를 사용하면 된다.

int i6 = 700;
String str6 = String.valueOf(i6);
System.out.println(str6); //"700"

long l7 = 9999999999L;
String str7 = String.valueOf(l7);
System.out.println(str7);

double d8 = 3.14;
String str8 = String.valueOf(d8);
System.out.println(str8); //"3.14"

boolean b9 = true;
String str9 = String.valueOf(b9);
System.out.println(str9); //"true"

2.12 String 과 기본타입 연산

String과 기본 타입간의 연산은 +이외에 안된다.
+ 는 연결연산(concatenate)이라고 한다.

// +이외에 안된다.
String s1 = "3";
String s2 = "4";
// System.out.println(s1 * s2); 안됨    

// + : 연결연산(concatenate)
int i3 = 3;
String s3 = "4";
String r3 = i3 + s3; // 연산결과가 String
System.out.println(r3); // 3 + "4" = "34"
System.out.println(3.14 + "hello");
System.out.println(false + "hi");

System.out.println(3 + 3 + "4"); 
//연산자 우선순위에 따라 3+3= 6 +"4" = 64

//기본타입 -> 스트링
//valueOf
//연결연산 빈문자열 더하기
int i6 = 99;
String s6 = String.valueOf(i6);
String s7 = i6 + "";

System.out.println(s6); //"99"
System.out.println(s7); //"99"

2.14 키보드 입력 데이터를 변수에 저장

키보드 입력 데이터를 변수에 저장해보자.
키보드로 부터 입력받는 것은 여러 방법이 있다. 가장 쉬운방법은 Scanner객체를 사용하는 것이다.
Scanner scanner = new Scanner(System.in);
System.in하면 printStream을 매개변수로 받는 생성자가 있다.
api 도큐먼트를 보면 많은 생성자중에 Scanner(InputStream source)이 있다.
System클래스의 in표준입력장치를 의미한다.
키보드로부터 읽어내는 객체를 만들어 내는 것이다.

nextLine() 행으로 한줄씩 읽는 메소드
매개변수로부터 한줄씩 읽는 기능도 있다.
Scanner scanner = new Scanner(input1);
scanner로부터 어떤 소스에있는 텍스트를 읽을 수 있다.

이것을 키보드로부터 입력받아보자.

public class C02Scanner {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("키보드로 작성해 보세요>");

        String str = scanner.nextLine();
        // 스캐너가 훑고지나가고 입력된 값을 리턴 그리고 다음 줄로 간다.
        // 엔터를 만날때까지 읽어감

        System.out.println("입력된 값 출력");
        System.out.println(str);
    }
}

2.15 next()

읽고나서 변환하는 변환하는 것이 불편하다. 읽자마자 변환시키고 싶다.
nextInt() nextDouble() nextBoolean() 등을 사용하면 편하다.

nextLine()하면 한줄을 다읽고 String으로 리턴한다.
integer를 하나하나 읽고 싶다면? nextInt()하면 된다.
하나의 토큰으로 읽어서 리턴한다.

String input = "3 33 555 50";
Scanner sc = new Scanner(input);

int num1 = sc.nextInt();
System.out.println(num1); //3
System.out.println(sc.nextInt()); //33
System.out.println(sc.nextInt()); //555
System.out.println(sc.nextInt()); //50

Scanner 연습문제

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int A = scanner.nextInt();
        int B = scanner.nextInt();

        System.out.println(A+B);
    }
}

  public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt();

        for (int i = 0; i < T; i++) {
            int A = scanner.nextInt();
            int B = scanner.nextInt();

            System.out.println(A + B);
        }
    }
}

public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int A = scanner.nextInt();
        int B = scanner.nextInt();
        int C = scanner.nextInt();

        if (B + C < 60) {
            System.out.printf("%d %d", A, B+C);
        } else {
            System.out.printf("%d %d", A+((B+C)/60)>=24?A+((B+C)/60)-24:A+((B+C)/60), (B+C)%60);
        }
    }
}

public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int X = scanner.nextInt();
        int N = scanner.nextInt();

        int sum = 0;
        for (int i = 0; i < N; i++) {
            int a = scanner.nextInt();
            int b = scanner.nextInt();

            sum += a * b;
        }
        if (sum == X) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }
    }
}

2023.02.15 후기

Scanner를 배우고 코딩테스트 문제를 몇 문제 풀어보았다. 과거에 풀었던 문제였지만 하나도 기억이 나지 않아 다시 풀었다. 백준 2525번 오븐시계의 경우 원래 풀었던 방식보다 코드가 짧아지고 시간이 줄어들었다. 아는 것이 조금이라도 더 늘어서 나아진 것이라고 봐야할까 싶다.

아직은 타입 부분이라서 수업 내용에 어려운 것은 없다. 개인적으로 객체 지향부터 공부하고 있으니 수업보다 빨리 나감으로써 수업시간은 복습의 시간이 될 것 같다. 오히려 잊지않고 상기시켜주는 역할을 함으로써 좋은 역할이 된다.

'국비 > Java' 카테고리의 다른 글

2023.02.21 19일차 Java  (0) 2023.02.21
2023.02.20 18일차 Java  (0) 2023.02.20
2023.02.17 17일차 Java  (0) 2023.02.17
2023.02.16 16일차 Java  (0) 2023.02.16
2023.02.14 14일차 Java  (0) 2023.02.14

+ Recent posts