///////
Search

StringBuilder / Wrapper class / 제네릭

태그
장서윤
자바기초
작성일
2022/09/30

String

: 원본 보존의 법칙! immutable : String 클래스의 경우 빈번하게 문자열을 변경할 때는 비효율적일 수 있다. => 문자열의 내용을 변경하는 스트링 클래스 메소드의 경우 새로운 String 객체를 생성하고 기존의 내용을 복사하기 때문에
package com.codelion.day10; public class Practice01 { public static void main(String[] args) { String str = "hello"; String str2 = "world"; String str3 = str + str2; String str4 = str.concat(str2); System.out.println(str3); String test = "hello" + 1; // hello1 형변환을 통해서 자동으로 더해준다 String test2 = "hello"; String test3 = test2 + "AAAA" + "world";//의경우, test2+AAAA 합쳐진 객체 생성, test2+AAAA+world 객체가 또 생성됨 } }
Java
복사
String이 원본 보존의 법칙인 이유 ! : final 상수로 정의되어있기 때문에 (한번 초기화되면 변경할 수 없음 따라서 새로운 객체를 생성해서 연결해주는 것)

StringBuffer / StringBuilder

: StringBuffer와 StringBuilder는 동일한 객체이다. 따라서 존재하는 함수도 동일
차이점 : Buffer는 쓰레드를 사용, Builder는 쓰레드를 사용하지 않는다

1) StringBuilder

package com.codelion.day10; public class Practice01String { public static void main(String[] args) { //String str = new String("1234"); StringBuilder sb = new StringBuilder("123"); sb.append(4567); //문자열 덧붙이기 sb.delete(0, 2); //문자열 삭제 마지막인덱스는 -1이다 0부터 2개 지워라 sb.replace(0, 3, "AB"); //문자열 일부 교체 sb.reverse(); //문자열 뒤집기 String sub = sb.substring(2, 4);// 2~(4-1)3까지 가져와라 System.out.println(sb); System.out.println(sb.toString()); } }
Java
복사
String substring 예제 강사님 : velog
문제
풀이
package com.codelion.day10; import java.util.Scanner; public class PracticeBuilder { public static void main(String[] args) { //i love you 문제 Scanner sc = new Scanner(System.in); String input = sc.nextLine(); for (int i = 0; i < input.length(); i++) { System.out.print(input.substring(i)); System.out.println(input.substring(0, i)); } } }
Java
복사

Math 클래스

package com.codelion.day10; public class Practice02 { public static void main(String[] args) { //라디언으로 변환 double radian45 = Math.toRadians(45); System.out.println("싸인 45" + Math.sin(radian45)); System.out.println("코싸인 45" + Math.cos(radian45)); System.out.println("단싸인 45" + Math.tan(radian45)); System.out.println("2의 16승 : " + Math.pow(2, 16)); System.out.println("로그 25 : " + Math.log(25)); int num = (int)(Math.random() * 100) + 1; System.out.println(Math.PI); } }
Java
복사

Calendar 클래스

Calendar c = Calendar.getInstance(); // 함수를 통해서 객체를 생성 System.out.println(c);
Java
복사
//출력 java.util.GregorianCalendar[time=1664502604809,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Seoul",offset=32400000,dstSavings=0,useDaylight=false,transitions=30,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=8,WEEK_OF_YEAR=40,WEEK_OF_MONTH=5,DAY_OF_MONTH=30,DAY_OF_YEAR=273,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=5,AM_PM=0,HOUR=10,HOUR_OF_DAY=10,MINUTE=50,SECOND=4,MILLISECOND=809,ZONE_OFFSET=32400000,DST_OFFSET=0]
Java
복사

Calendar

package com.codelion.day10; import java.util.Calendar; public class Practice02Calender { public static void main(String[] args) { Calendar now = Calendar.getInstance(); // 함수를 통해서 객체를 생성 System.out.println(now); int year = now.get(Calendar.YEAR); int month = now.get(Calendar.MONDAY); int date = now.get(Calendar.DATE); System.out.println(year + ":" + month + ":" + date); int hour12 = now.get(Calendar.HOUR); int hour24 = now.get(Calendar.HOUR_OF_DAY); int minute = now.get(Calendar.MINUTE); int second = now.get(Calendar.SECOND); System.out.println(hour12 + ":" + hour24 + ":" + minute + ":" + second); int milliSecond = now.get(Calendar.MILLISECOND);//1000초 int timeZone = now.get(Calendar.ZONE_OFFSET);// 시스템상에 설정된 타임존 int lastDay = now.getActualMaximum(Calendar.DATE);//이달의 마지막 날 System.out.println(milliSecond); System.out.println(timeZone + ":" + lastDay); } }
Java
복사
Calendar 예제
package com.codelion.day10; import java.util.Calendar; class Time { private int now; private String answer; public Time(int now) { this.now = now; } public String nowDate() { if (now > 4 && now < 12) { answer = "Good Morning"; } else if (now >= 12 && now < 18) { answer = "Good Afternoon"; } else if (now >= 18 && now < 22) { answer = "Good Evening"; } else { answer = "Good night"; } return answer; } } public class Practice03Mini { public static void main(String[] args) { Calendar now = Calendar.getInstance(); int hour = now.get(Calendar.HOUR_OF_DAY);//24시간 int minute = now.get(Calendar.MINUTE); System.out.println("현재 시간은 " + hour + "시 " + minute + "분입니다"); System.out.println(new Time(hour).nowDate()); } }
Java
복사

래퍼 클래스 (Wrapper class)

: 기본 자료형을 감싼 래퍼 클래스
public class Project03Wrapper { public static void main(String[] args) { Integer n1 = Integer.valueOf(5); Integer n2 = Integer.valueOf("1234"); int num = n1 + n2; //객체인데 값이 더해지는 이유는, 박싱/언박싱 때문 -> 객체를 값으로 변경해준다 System.out.println(num); } }
Java
복사
wrapper class 사용하는 이유 : 메소드의 인수로 객체 타입만이 요구되면, 기본 타입의 데이터를 그대로 사용할 수는 없다 이때에는 기본 타입의 데이터를 먼저 객체로 변환한 후 작업을 수행할 수 있다.ㄴ

Boxing , Unboxing

: 객체를 기본자료형으로 변경(Unboxing)해주거나 기본자료형 값을 객체로 Boxing 해주는 것
예제)
package com.codelion.day10; public class Practice04Wapper { public static void main(String[] args) { Integer n1 = Integer.valueOf(5); Integer n2 = Integer.valueOf("1234"); int num = n1;//언박싱 Integer n3 = 5;//박싱 int num1 = 5; int num2 = 5; int num3 = num1 + num2; Integer num4 = num1 + num2; //이렇게 연산하는 경우는 거의 없음. 쓰이는 곳은 제네릭 사용시 제네릭은 객체만 들어갈 수 있기 때문에 System.out.println(num3); } }
Java
복사

오토박싱과 오토언박싱

Integer WrapperClass

package com.codelion.day10; import java.math.BigInteger; import java.util.ArrayList; public class Practice04Wapper { public static void main(String[] args) { ArrayList<Integer> arr = null; Integer n1 = Integer.valueOf(5); Integer n2 = Integer.valueOf("1234"); System.out.println("큰 수: " + Integer.max(n1, n2)); System.out.println("작은 수: " + Integer.min(n1, n2)); System.out.println("합 : " + Integer.sum(n1, n2)); System.out.println("2진수 표현 : " + Integer.toBinaryString(12)); //이진수 값으로 변경해줌 System.out.println("2진수 표현 : " + Integer.toBinaryString(100000)); //이진수 값으로 변경해줌 System.out.println("8진수 표현 : " + Integer.toOctalString(100000)); //8진수 값으로 변경해줌 System.out.println("16진수 표현 : " + Integer.toHexString(12)); //16진수 값으로 변경해줌 System.out.println("정수의 최대값 : " + Integer.MAX_VALUE); System.out.println("정수의 최소값 : " + Integer.MIN_VALUE); System.out.println("Long의 최대값 : " + Long.MAX_VALUE); System.out.println("Long의 최소값 : " + Long.MIN_VALUE); //Long형의 범위를 넘어갈 때 BigInteger big1 = new BigInteger("999999999999999999999999999"); BigInteger big2 = new BigInteger("-999999999999999999999999999"); BigInteger result = big1.add(big2);// + - 등의 연산자 사용 못함, 함수로 값을 계산 System.out.println("결과: " + result); BigInteger multiply = big1.multiply(big2);//곱하기 System.out.println(multiply); } }
Java
복사

제네릭 (generic)

: 자바 1.5 버전 이상부터 사용가능 (어노테이션, enum, 제네릭)
제네릭 이전 버전에서는 어쩔 수 없이 형 변환의 과정이 수반 되어야 했다. 제네릭을 도입하면서 이런것들을 해결
정보 은닉이 나온것은 접근성을 막고 컴파일 에러를 내는 것 제네릭을 도입한 이유는 문제가 생길 경우 컴파일 에러를 내서 이전에 발생했던 문제들을 예방하고 막기 위해서
제네릭 예제
제네릭 사용 이전
package com.codelion.day10; class Apple { @Override public String toString() { return "나는 사과입니다."; } } class Orange { @Override public String toString() { return "나는 오렌지입니다."; } } class Box { private Object obj; public void set(Object obj) { this.obj = obj; } public Object get() { return obj; } } public class Practice04Generic { public static void main(String[] args) { Box aBox = new Box(); Box oBox = new Box(); aBox.set(new Apple()); oBox.set(new Orange()); Apple ap = (Apple) aBox.get();//형변환 과정이 반드시 필요하다 Orange og = (Orange) oBox.get(); System.out.println(ap); System.out.println(og); } }
Java
복사

제네릭 이전 버전의 문제

강제 형변환 과정이 반드시 필요하다
프로그래머의 실수가 컴파일 과정에서 반영되지 않는다.
❗️실수가 실행과정에서 조차 발견되지 않음
package com.codelion.day10; class Apple { @Override public String toString() { return "나는 사과입니다."; } } class Orange { @Override public String toString() { return "나는 오렌지입니다."; } } class Box { private Object obj; public void set(Object obj) { this.obj = obj; } public Object get() { return obj; } } public class Practice04Generic { public static void main(String[] args) { Box aBox = new Box(); Box oBox = new Box(); aBox.set(new Apple()); oBox.set(new Orange()); Apple ap = (Apple) aBox.get();//문제점1. 강제 형변환 과정이 반드시 필요하다 Orange og = (Orange) oBox.get(); aBox.set("apple"); //문제점2. 프로그래머의 실수가 컴파일 과정에서 반결되지 않는다. //Apple ap2 = (Apple) aBox.get(); //에러 발생 java.lang.ClassCastException oBox.set("orange"); System.out.println(oBox.get());//문제점3. 실수가 실행과정에서 조차 별견되지 않음 //객체가 아닌 문자열로 들어갔지만 발견하지 못함 System.out.println(ap); System.out.println(og); } }
Java
복사

제네릭 기반의 인스턴스 생성

타입 매개변수(Type prameter) T
타입 인자(Type Argument)
<Apple>
Java
복사
매개변수화 타입(parameterized Type)
Box<Apple>
Java
복사

제네릭 문법

: 뒷 제네릭 정의는 생략이 가능하다 자동으로 컴파일러가 앞에 맞춰서 넣어줌
Box02<Apple> abox = new Box02<Apple>();
Java
복사
Box02<Apple> abox = new Box02<>();
Java
복사
package com.codelion.day10; class Box02<T> { private T obj; public void set(T obj) { this.obj = obj; } public T get() { return obj; } } public class Practice05 { public static void main(String[] args) { Box02<Apple> abox = new Box02<Apple>(); Box02<Orange> obox = new Box02<Orange>(); abox.set(new Apple()); obox.set(new Orange()); //abox.set("apple"); //개선2. 지정 객체 이 외의 다른 타입이 들어가지 않는다 Apple ap = abox.get(); //개선1. 형 변환 하지 않는다. Orange op = obox.get(); System.out.println(ap); System.out.println(op); } }
Java
복사

제네릭의 장점

특정 타입을 지정할 수 있다
컴파일시 타입이 이미 결정되어진다
예제가 변경된 모습)

제네릭 타입 복수 예제

관습적으로 사용하는 타입 약자가 존재하지만 프로그래머가 정의 가능
package com.codelion.day10; class Box02<T, V> { private T string; private V integer; public void set(T string, V integer) { this.string = string; this.integer = integer; } @Override public String toString() { return string + " & " + integer; } } public class Practice05 { public static void main(String[] args) { Box02<String, Integer> box02 = new Box02<String, Integer>(); box02.set("Apple", 25); System.out.println(box02); } }
Java
복사

제네릭 클래스의 타입 인자 제한하기

인스턴스 생성시 타입 인자로 number 또는 이를 상속하는 클래스만 올 수 있다.
: 코드 추려내기
package com.codelion.day10; class Box03<V extends Number> { private T string; private V integer; public void setInteger(V integer) { this.integer = integer; } public void set(T string, V integer) { this.string = string; this.integer = integer; } @Override public String toString() { return string + " & " + integer; } } public class Practice06 { public static void main(String[] args) { Box03<Integer> iBox = new Box03<>(); iBox.setInteger(24); System.out.println(iBox.get()); Integer[] intArray = {1, 2, 3}; String[] stringArray = {"hello", "world"}; printArray(intArray); printArray(stringArray); } public static void printArray(Object[] arr) { for (Object t : arr) { System.out.println(t); } } }
Java
복사

️제네릭 메소드의 정의

제네릭 메소드라는 것을 명시하기 위해서 클래스명 앞에 <T>를 명시해주는것
<T> : <T> Box<T> makeBox(T o) {} 중에서 해당 메서드 타입이 <T> 라는 것
Box<T> : return 타입
main
제네릭 메소드의 T는 메소드 호출 시점에 결정 (생략 가능)