[java] 기초(4)

세상을 바꾸는 개발자·2023년 2월 27일
0

LikeLion

목록 보기
4/5

자바에서의 한글 표현

class Main {
public static void main(String[] args) {
System.out.println(isHanguel('안'));
System.out.println(isHanguel('녕'));
System.out.println(isHanguel('하'));
System.out.println(isHanguel('세'));
System.out.println(isHanguel('요'));
System.out.println(isHanguel('.'));
}
static boolean isHanguel(char c) { //한글인지 검사
    return c >= '가' && c <= '힣';
}

System.out.println(isHanguel(' ')); 처럼 공백은 가능한데
System.out.println(isHanguel('')); 는 안됨


equals

char c1 = 'a'; c1은 'a'를 저장
String s1 = "a"; s1은 'a'를 가지고 있는 주소를 저장

class Main {
    public static void main(String[] args) {
        char c1 = 'a';'
        char c2 = 'a';'
        
        System.out.println(c1 == c2); // true
        
        // String 은 char의 순서있는 조합이다.
        String s1 = "하하";
        String s2 = "하";
        s2 += "하";

        System.out.println(s1 == s2); // false
        System.out.println(s1.equals(s2)); // true
    }
}

s1, s2는 내용은 같아도 서로 다른 객체가 같은 내용을 가지고 있기 때문에 다름

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person(13);
        Person p2 = new Person(13);

        System.out.println(p1);
        System.out.println(p2);

        System.out.println("p1 == p2 : " + (p1 == p2)); // 리모콘 끼리 비교, 당연히 false
        System.out.println("p1.equals(p2) : " + p1.equals(p2)); // 객체끼리 비교, 하지면 여기서는 Person 클래스에 equals 메서드를 오버라이드 하지 않아서 false
        // 즉 객체 비교를 하려면 해당 클래스에 equals 메서드를 오버라이드 해야 한다.

        String s1 = "하하"; // 문장객체 생성됨
        String s2 = "하하"; // 여기서는 기존의 객체의 리모콘만 리턴, 이유 : 메모리 절약

        System.out.println("s1 : " + s1);
        System.out.println("s2 : " + s2);

        System.out.println("s1 == s2 : " + s1 == s2);
        System.out.println("s1.equals(s2) : " + s1.equals(s2));

        String s3 = new String("하하"); // 재활용 x
        String s4 = new String("하하"); // 재활용 x

        System.out.println("s3 : " + s3);
        System.out.println("s4 : " + s4);

        System.out.println("s3 == s4 : " + s3 == s4);
        System.out.println("s3.equals(s4) : " + s3.equals(s4));
    }
}

class Person {
    private int age;

    public Person(int age) { this.age = age; }
}

String s1 = "하하";
String s2 = "하하";
자바는 메모리를 절약하기 위해 최대한 같은 것은 안만드려고 함(재활용) -> 기존의 객체의 리모콘만 리턴
-> 같

String s1 = new String("하하");
String s1 = new String("하하");
new String을 사용하여 생성했을 경우에는 재활용하지 않음 (일반적으로 사용x)


StringBuilder

class Main {
    public static void main(String[] args) throws IOException {
        String s = "*";
        s+="*";
        s+="*";
        System.out.println(s);
        
        //StringBuilder가 더 좋음
        StringBuilder sb = new StringBuilder();
        sb.append("*");
        sb.append("*");
        sb.append("*");

        System.out.println(sb.toString());
    }
}

StringBuilder - "*" 하나만 가지고 있다가 마지막에 합침. 메모리 절약


toString

객체의 출력 방식을 커스터마이즈. 디버깅이 편함
toString메서드는 객체가 문장으로서 취급되어야 할 때, 자바에서 알아서 호출해준다.

// Object 클래스와 toString
class Main {
    public static void main(String[] args) {
        사람 a사람1 = new 사람("홍길동", 22);
        사람 a사람2 = new 사람("홍길순", 23);
        System.out.println(a사람1);
        System.out.println(a사람2);
    }
}
class 사람 extends Object {
    String 이름;
    int 나이;
    사람(String 이름, int 나이) {
        this.이름 = 이름;
        this.나이 = 나이;
    }

    @Override //어노테이션. 주석 같은 느낌
    public String toString() {
        return "사람[이름=" + 이름 + ",나이=" + 나이 + "]";
    }
}

a사람1에 대한 이름, 나이가 바로 출력되도록 하려면 Object클래스의 toString()을 사용
a사람1.이름 a사람1.나이 대신 a사람1만 넣어도 실행 가능


static

static 메서드는 오직 static메서드나 static 변수에만 접근이 가능하다.

class Main {
    public static void main(String[] args) {
        사람.걷다();
        사람.걷다();
        사람.걷다();
    }
}

class 사람 {
    //int 속도 = 3; // instance(대리점)
   	static int 속도 = 3;

    // static(본사) 메서드
    static void 걷다() {
        System.out.println("걷는다 : 속도(" + 속도 + "km/h)"); // 불가능(x)
        숨쉬다(); // 가능
        생각하다(); // 불가능(x)
    }

    static void 숨쉬다() {
        System.out.println("숨쉬다.");
    }

    static void 생각하다() {
        System.out.println("생각하다.");
    }
}

static 사용 안할 시, new 사람().걷다();


Object, Generic

자바의 모든 객체와 비객체는 Object형 변수에 연결될 수 있다.

원래 코드 : 저장소 계열의 클래스들이 비슷함. 중복되는 코드가 많음.

class Main {
    public static void main(String[] args) {
        Int저장소 a저장소1 = new Int저장소();
        
        a저장소1.setData(30);
        int a = a저장소1.getData();
        
        System.out.println(a);
        
        Double저장소 a저장소2 = new Double저장소();
        
        a저장소2.setData(5.5);
        double b = a저장소2.getData();
        
        System.out.println(b);
        
        
        사과저장소 a저장소3 = new 사과저장소();
        
        a저장소3.setData(new 사과());
        사과 c = a저장소3.getData();
        
        System.out.println(c);
    }
}

class Int저장소 {
    Object data;
    
    int getData() {
        return (int)data;
    }
    
    void setData(Object inputedData) {
        this.data = inputedData;
    }
}

class Double저장소 {
    Object data;
    
    double getData() {
        return (double)data;
    }
    
    void setData(Object inputedData) {
        this.data = inputedData;
    }
}

class 사과 {
}

class 사과저장소 {
    Object data;
    
    사과 getData() {
        return (사과)data;
    }
    
    void setData(Object inputedData) {
        this.data = inputedData;
    }
}



개선한 코드1 : Object를 사용하여 저장소 클래스들을 하나로 통합함. 사용자 입장에서 데이터를 받을 때 매번 형변환을 해야하는 불편함이 있음.

class Main {
    public static void main(String[] args) {
        저장소 a저장소1 = new 저장소();
        
        a저장소1.setData(30);
        int a = (int)a저장소1.getData(); //int 형변환 해줘야함
        
        System.out.println(a);
        
        저장소 a저장소2 = new 저장소();
        
        a저장소2.setData(5.5);
        double b = (double)a저장소2.getData(); //double 형변환 해줘야함
        
        System.out.println(b);
        
        
        저장소 a저장소3 = new 저장소();
        
        a저장소3.setData(new 사과());
        사과 c = (사과)a저장소3.getData(); //사과 형변환 해줘야함
        
        System.out.println(c);
    }
}

class 저장소 {
    Object data;
    
    Object getData() {
        return data;
    }
    
    void setData(Object inputedData) {
        this.data = inputedData;
    }
}

class 사과 { } 



##개선한 코드2 : 제너릭을 이용하여 각 저장소 클래스들을 하나로 통합한 것만 아니라, 사용할 때도 편리

class Main {
	public static void main(String[] args) {
		저장소<Integer> a저장소1 = new 저장소<>();
		
		a저장소1.setData(50);
		int a = a저장소1.getData();
		
		System.out.println(a);
		
		저장소<Double> a저장소2 = new 저장소<>();
		
		a저장소2.setData(5.5);
		double b = a저장소2.getData();
		
		System.out.println(b);
		
		
		저장소<사과> a저장소3 = new 저장소<>();
		
		a저장소3.setData(new 사과());
		사과 c = a저장소3.getData();
		
		System.out.println(c);
	}
}

class 저장소<T> {
	Object data;
	
	T getData() {
		return (T)data;
	}
	
	void setData(T inputedData) {
		this.data = inputedData;
	}
}


class 사과 {
}

저장소<Integer> a저장소1 = new 저장소<>(); 형태 알기



Scanner

import java.util.InputMismatchException;
import java.util.Scanner;

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

        int input = 0;

        while ( true ) {
            System.out.printf("숫자 : ");

            try {
                input = sc.nextInt(); // 대기, 숫자 하나 입력될 때 까지
                break;
            }
            catch ( InputMismatchException e ) {
                sc.nextLine(); // 버퍼를 비운다.
                System.out.println("숫자를 입력해주세요.");
            }
        }

        System.out.printf("입력된 숫자 : %d\n", input);

        sc.close();
    }
}

Scanner sc = new Scanner(System.in); 대신
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 사용 가능

profile
초심 잃지 않기

0개의 댓글