카테고리 없음

2024. 7. 10. (수) 슈퍼코딩 부트캠프 Day 33 / 주특기 3주차

태영9922 2024. 7. 10. 16:30

 

1. StringBuilder / StringBuffer 사용하기

그냥 String에 concat이나 +를 사용하여 문자열을 추가하게 되면 Heap에 추가할때마다 새로운 String 객체가 생성되어 참조되지 않는 Garbage가 많아지기 때문에,

이런 문제를 해결하기 위해서 StringBuilder 또는 StringBuffer를 사용한다.

public static void main(String[] args) {
        // +로 String 연결
        String str = "";
        long startTime = System.currentTimeMillis(); //시작시간 체크
        for (int i = 0; i < 50000; i++) {
            str += "Cat";
        }
        System.out.println(str);

        long endTime = System.currentTimeMillis(); //끝나는 시간 체크
        long 걸린시간 = endTime - startTime;

        StringBuilder sb = new StringBuilder(str);
        long startTime2 = System.currentTimeMillis();
        for (int i = 0; i < 50000; i++) {
            sb.append("Cat");
        }
        System.out.println(sb.toString());
        long endTime2 = System.currentTimeMillis();
        long 걸린시간2 = endTime2 - startTime2;
        System.out.println("String += 사용 : " + 걸린시간 + "ms\nStringBuilder.append 사용 : " + 걸린시간2 + "ms");
    }

// String += 사용 : 490ms
// StringBuilder.append 사용 : 3ms
 

2. Java Class 클래스

  • 클래스의 구성요소 : 필드(객체의 데이터가 저장되는 곳), 생성자(객체 생성시 초기화 역할), 메소드(객체의 동작에 해당하는 실행 블록) 으로 구성
  • Class 클래스 : 클래스 정보 얻어오는 클래스
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Customer customer = new Customer("민철");
        Class clazz = customer.getClass(); //customer 클래스 가져오기-> 객체.getClass()
        //Class clazz1 = Customer.class; //class 가져오기2 -> 클래스이름.class

        Constructor[] constructors = clazz.getConstructors(); //클래스의 생성자 가져오기
        for (Constructor constructor : constructors) {
            System.out.println(constructor); //Customer 클래스의 생성자 출력
        }

        Method[] methods = clazz.getMethods(); //클래스의 메소드 가져오기
        for (Method method : methods) {
            System.out.println(method); //Customer 클래스의 메소드 출력
        }

        Field[] fields = clazz.getFields(); //클래스의 필드 가져오기, public 만 가져올 수 있음
        for (Field field : fields) {
            System.out.println(field);
        }

        Field[] declaredFields = clazz.getDeclaredFields(); //public 아닌 필드도 가져올수 있음
        for (Field field : declaredFields) {
            System.out.println(field);
        }

        Customer customer1 = (Customer) clazz.getConstructor(String.class).newInstance("민철");
        //clazz를 통해 인스턴스 생성 Object 타입 -> 다운캐스팅 필요
        customer1.printMyInfo(); //Customer의 메소드 사용 가능
    }
 

- Class 클래스가 필요한이유 : Java Reflection 기술과 같이 쓰임. Spring AOP 에서 사용. 추후 배울 예정.

 

3. Java System 클래스 (유틸리티 클래스)

  • 운영체제 시스템 관련 기능 수행(ex. 입출력관리, 시간측정, 환경변수 접근, GC 호출 등)

 

4. Java Math 클래스 (유틸리티 클래스)

  • 기본 수식 연산자 외 여러 수학 계산 관련 메소드 제공(ex. abs절대값, ceil올림, max, min, sqrt제곱근, round반올림, random 등)

☑️ Wrapper, Generic

 

1. Wrapper 클래스

  • 자바 기본타입(int, float, byte, char 등) 과 매핑된 클래스
  • 박싱 : 기본타입 -> Wrapper 클래스 // 언박싱 : Wrapper 클래스 -> 기본타입
Integer num = new Integer(10); //박싱
int n = num.intValue();  //언박싱

Integer num2 = 10; //오토박싱 -> 박싱 기능 자동으로 수행
int n2 = num2;  //오토언박싱 -> 언박싱 기능 자동으로 수행

Character ch1 = new Character('X'); //박싱
char c1 = ch1.charValue(); //언박싱

Character ch2 = 'X'; //오토박싱 -> 박싱 기능 자동으로 수행
char c2 = ch2; //오토언박싱 -> 언박싱 기능 자동으로 수행

Integer result1 = num + num2; // 20
Integer result2 = n + n2; //20
int result3 = num * n2; // 100

Integer integer1 = null; //가능
int int1 = null; //불가능
 
  • Wrapper 클래스가 존재하는 이유?

- 객체지향적 프로그래밍 실현 & 자료구조 일관성 유지, Java 라이브러리 사용 지원, Generic 프로그래밍 지원

 

2. Generic 살펴보기

  • 안전하게 같은 코드를 여러 참조형에서 사용하여 코드 재사용성을 올리는 프로그래밍 기법
public class 클래스<T> {...}
public interface 인터페이스<T> {...}
 
// NON GENERIC

public class GeneralPrint {
    private Object material;

    public void printMyInfo() {
        System.out.println(material + "를 출력합니다");
    }

    public Object getMaterial() {
        return material;
    }

    public void setMaterial(Object material) {
        this.material = material;
    }
}

...

public class PrintSituation {
    public static void main(String[] args) {
        //GeneralPrint를 Object로 선언, 다운캐스팅 필요
        GeneralPrint print = new GeneralPrint();
        print.setMaterial("설계도");

        String meterial = (String) print.getMaterial();
        print.printMyInfo();

        GeneralPrint print2 = new GeneralPrint();
        print2.setMaterial(1235);

        Integer intMaterial = (Integer) print2.getMaterial();
        print2.printMyInfo();

        GeneralPrint print3 = new GeneralPrint();
        print3.setMaterial(true);

        Boolean booleanMaterial = (Boolean) print3.getMaterial();
        print3.printMyInfo();
    }
}
 
//GENERIC

public class GeneralPrint<T> {
    private T material;

    public void printMyInfo() {
        System.out.println(material + "를 출력합니다");
    }

    public T getMaterial() {
        return material;
    }

    public void setMaterial(T material) {
        this.material = material;
    }
}

...

public class PrintSituation {
    public static void main(String[] args) {
        //<> 여기에는 Wrapper 클래스만 가능, int, float, double 등등 기본형 불가
        GeneralPrint<String> print = new GeneralPrint();
        print.setMaterial("설계도");

        String meterial = print.getMaterial();
        print.printMyInfo();

        GeneralPrint<Integer> print2 = new GeneralPrint();
        print2.setMaterial(1235);

        Integer intMaterial = print2.getMaterial();
        print2.printMyInfo();

        GeneralPrint<Boolean> print3 = new GeneralPrint();
        print3.setMaterial(true);

        Boolean booleanMaterial = print3.getMaterial();
        print3.printMyInfo();

        //<> 안붙이면 Object 타입으로 캐스팅
        GeneralPrint print4 = new GeneralPrint();
        print.setMaterial("설계도1");

        //다운캐스팅 필요
        String meterial1 = (String) print4.getMaterial();
        print.printMyInfo();

    }
}
 

3. Generic 심화

  • Static은 Generic 적용할 수 없음. 왜냐? Static은 클래스 로드 시 생성되는데 Generic은 인스턴스 생성 시 생성
  • 두 개 이상도 가능
  • 자료형 제한하기 : extends로 범위를 좁히기
public class Point<T extends Number, V extends Number> { //범위를 Number의 하위 클래스들로 한정시키기
    private T x;
    private V y;

    public Point(T x, V y) {
        this.x = x;
        this.y = y;
    }

    public T getX() {
        return x;
    }

    public V getY() {
        return y;
    }

    public Double calculateDistance() {
        Double num1 = (this.x).doubleValue();
        Double num2 = (this.y).doubleValue();

        return Math.sqrt(Math.pow(num1, 2) + Math.pow(num2, 2));
    }
}

...
public class PointSituation {
    public static void main(String[] args) {
        Point<Integer, Integer> point = new Point<>(1, 5);
        Point<Integer, Double> point1 = new Point<>(1, 4.5);
        Point<Double, Double> point2 = new Point<>(1.5, 5.5);

        System.out.println(point.calculateDistance());
        System.out.println(point1.calculateDistance());
        System.out.println(point2.calculateDistance());

        Point<String, Integer> point3 = new Point<>("A", 1); //에러 발생
        System.out.println(point3.calculateDistance());
    }
}
 

 

#슈퍼코딩, #1:1관리형부트캠프, #백엔드, #backend, #백엔드공부, #개발공부, #백엔드개발자 #취준일기, #취준기록, #취뽀, #빡공, #HTML/CSS, #javascript, #react , #java, #spring