본문 바로가기
카테고리 없음

4/10 - java.base 모듈 (2), 제네릭, 멀티 스레드

by Jiwon_Loopy 2025. 4. 12.
반응형

목차


문자열 클래스


  • String
    • 문자열 저장 및 조작
    • 느림
  • StringBuilder
    • 효율적인 문자열 조작
    • 빠름
    • String vs StringBuilder 속도 비교
    package ch12.sec05;
    
    public class StringBuilderEx {
    
    	public static void main(String[] args) {
    		String str = "a";
    		
    		long start = System.currentTimeMillis();
    		for(int i= 0; i< 100000; i++) {
    			str += i;
    		}
    		long end = System.currentTimeMillis();
    		System.out.println("소요시간: "+ (end - start));
    		
    
    		long start2 = System.currentTimeMillis();
    		StringBuilder str2 = new StringBuilder();
    		for(int i= 0; i< 100000; i++) {
    			str2.append(str);
    		}
    		long end2 = System.currentTimeMillis();
    		System.out.println("소요시간: "+ (end2 - start2));
    	}
    
    }
    
    출력 결과
    
    소요시간: 4236
    소요시간: 7
    
  • StringTokenizer
    • 구분자로 연결된 문자열 분리
  • substring(1번 인덱스,2번 인덱스)
    • 1번 인덱스부터 2번 -1 인덱스 까지 잘라냄
    • 매개변수가 1개이면 해당 인덱스부터 끝까지 잘라냄
  • length()
    • 문자열의 길이
  • indexOf(매개변수)
    • 해당 키워드의 매개변수가 포함된 첫 번째 인덱스
  • lastIndexOf(매개변수)
    • 해당 키워드의 매개변수가 포함된 마지막 인덱스
  • toUpperCase()
    • 대문자로 변경
  • toLowerCase()
    • 소문자로 변경
  • trim()
    • 앞 뒤 공백 제거
  • replace(앞,뒤)
    • 문자열 변환 (앞 매개변수를 뒤 매개변수로)
  • startsWith(문자열)
    • 매개변수 문자열로 시작하는 여부
  • endsWith(문자열)
    • 매개변수 문자열로 끝나는 여부
package ch12.sec05;

public class StringEx {
	public static void main(String args[]) {
		// indexOf (해당 키워드의 첫 번째 위치)
		String greet = "안녕하세요";
		System.out.println(greet.indexOf("하")); // 2

		// 단어의 포함 여부 (없으면 -1, 있으면 0이상)
		if (greet.indexOf(".") > -1) // 매개변수가 문자열에 있는지
		
		// 문자열 자르기
		System.out.println(greet.substring(1)); // 녕하세요
		System.out.println(greet.substring(1,3)); // 녕하

		// 동적으로 어떤 값부터 잘라내야하는 구조
		System.out.println(greet.substring(greet.indexOf("하"))); // 하세요

		// 대소문자 변경
		String test = "AbC";
		System.out.println(test.toUpperCase()); // ABC
		System.out.println(test.toLowerCase()); // abc

		// 공백 제거
		String test2 = "                    a bc                       ";
		System.out.println(test2.trim()); // 중간 공백은 제거하지 못함
		System.out.println(test2.replace(" ", "")); // 모든 공백 제거

		// 특정 문자열로 시작하는지 여부
		String test3 = "Mr.Lee";
		System.out.println(test3.startsWith("Mr")); // true
		System.out.println(test3.endsWith("Lee")); // true

		// 문자열로 변환
		int a = 1;
		String s1 = a + "";
		String s2 = String.valueOf(a); // "a"
	}

}

포장 클래스


  • 컬렉션 객체를 위해 존재
  • 객체를 생성하는데 목적이 있음
  • 기본 타입을 포장하고 있어서 포장 클래스
  • Integer, Character, Long, Double …
  • equals()로 비교해야 한다.
  • 박싱
    • 기본 타입의 값을 포장 객체로 만드는 과정
  • 언박싱
    • 포장 객체에서 기본 타입의 값을 얻어내는 과정
Integer obj = 100; // 박싱
int value = obj; // 언박싱

수학 클래스


  • abs
    • 절대 값
  • ceil
    • 올림 값
  • floor
    • 버림 값
  • max
    • 최대 값
  • min
    • 최소 값
  • random
    • 랜덤 값
  • round
    • 반올림 값

날짜와 시간 클래스


  • Month는 0부터 시작이므로 1을 더해주어야 함
  • Date
    • 날짜 정보 전달
    package ch12.sec05;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateEx {
    
    	public static void main(String[] args) {
    		Date now = new Date();
    		System.out.println(now);
    		
    		SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
    		String strNow2 = sdf.format(now);
    		System.out.println(strNow2);
    		
    		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초");
    		String strNow2 = sdf2.format(now);
    		System.out.println(strNow2);
    	}
    
    }
    
    출력 결과
    
    Thu Apr 10 12:05:31 KST 2025
    2025.04.10 12:05:31
    2025년 04월 10일 12시 08분 08초
    
  • Calendar
    • 다양한 시간대 별로 날짜와 시간을 얻을 때 사용
    [JAVA] D-day 계산하기 [Calendar.getInstance(), getTimeInMillis()]
  • LocalDateTime
    • 날짜와 시간 조작
    • 가장 많이, 대중적으로 사용
    [Java] LocalDate, LocalDateTime 날짜, 시간 더하기 및 빼기

형식 클래스


  • Format 클래스
    • DecimalFormat
      • 숫자를 형식화된 문자열로 변환
      package ch12.sec09;
      
      import java.text.DecimalFormat;
      
      public class DecimalFormatExample {
      	public static void main(String args[]) {
      		
      		double a = 123456789.123;
      		
      		DecimalFormat sdf = new DecimalFormat("#,###.####"); // 자릿수만큼 # (3자리 반올림, 4째 자리에서 반올림)
      		System.out.println(sdf.format(a));
      		
      		DecimalFormat sdf2 = new DecimalFormat("#,###.0000"); // 자릿수가 부족하면 채워줌 (0), #은 채워주지 않음
      		System.out.println(sdf2.format(a));
      	}
      }
      
      출력 결과
      
      123,456,789.123  // 3째 자리까지만 반올림
      123,456,789.1230 // 부족한 4번째가 0으로 채워짐
      
    • SimpleDateFormat
      • 날짜를 형식화된 문자열로 변환

정규 표현식


  • 정해져 있는 문자열 형식 검증에 사용

자바스크립트 자주 쓰는 정규식 모음 (이메일, 핸드폰, 주민번호 등)

  • 정규식 표현
boolean result = Pattern.matches("정규식","검증할 문자열");
package ch12.sec10;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PatternExample {
	public static void main(String args[]) {
		String regExp = "(02|010)-\\\\d{3,4}-\\\\d{4}";
		String data = "010-123-4567";
		
		boolean result = Pattern.matches(regExp, data);
		
		if(result) {
			System.out.println("정규식과 일치합니다.");
		}
		else {
			System.out.println("정규식과 일치하지 않습니다.");
		}
		
		regExp = "\\\\w+@\\\\w+\\\\. \\\\w+(\\\\. \\\\w+)?";
		data = "angel@mycompanycon";
		result = Pattern.matches(regExp, data);
		
		if(result) {
			System.out.println("정규식과 일치합니다.");
		}
		else {
			System.out.println("정규식과 일치하지 않습니다.");
		}
		
		// 컴파일
		// 속도가 빨라짐
		Pattern p = Pattern.compile("b[a-z]*"); // b로 시작하고, 영문 소문자 0개 이상
		Matcher m = p.matcher("ball");
		System.out.println(m.matches());
		System.out.println(p.matcher("batman").matches());
	}
}

출력 결과

정규식과 일치합니다.
정규식과 일치하지 않습니다.
// 컴파일
// 속도가 빨라짐
Pattern p = Pattern.compile("b[a-z]*"); // b로 시작하고, 영문 소문자 0개 이상
Matcher m = p.matcher("ball");
System.out.println(m.matches());
System.out.println(p.matcher("batman").matches());

String source = "122 안녕하세요 저는 홍길동입니다. 어떻고 저떻고 제 전화번호는 010-1234-5678입니다. 제 친구 번호는 010-2222-3333입니다.";
// 미리 컴파일
p = Pattern.compile("(0\\\\d{1,2})-(\\\\d{3,4})-(\\\\d{4})"); // ( )는 그룹핑 (통째로, 개별로 찾아낼 수 있음)
m = p.matcher(source);
while(m.find()) { // 찾으면 true
	System.out.println("찾음");
	System.out.println(m.group());
	System.out.println(m.group(1) + "은 1번그룹");
	System.out.println(m.group(2) + "은 2번그룹");
	System.out.println(m.group(3) + "은 3번그룹");
	System.out.println();
}
		
		
출력 결과
		
정규식과 일치합니다.
정규식과 일치하지 않습니다.
true
true
찾음
010-1234-5678
010은 1번그룹
1234은 2번그룹
5678은 3번그룹

찾음
010-2222-3333
010은 1번그룹
2222은 2번그룹
3333은 3번그룹

리플렉션


  • 메타 정보를 프로그램에서 읽고 수정하는 행위
  • 메타 정보
    • 패키지 정보
    • 타입 정보
    • 멤버(생성자, 필드, 메소드)정보

어노테이션


  • @로 작성되는 요소
  • 컴파일 시 사용하는 정보 전달
  • 빌드 툴이 코드를 자동으로 생성할 때 사용하는 정보 전달
  • 실행 시 특정 기능을 처리할 때 사용하는 정보 전달
public @interface 어노테이션 명 { }
package ch12.sec12;

import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

public class PrintAnnotation {

	@Target({ ElementType.METHOD }) // 넣어줄 요소
	@Retention(RetentionPolicy.RUNTIME) // 실행 수명 주기
	public @interface PrintAnnotations {
		String value() default "-";

		int number() default 15;
	}
}

제네릭


  • 결정되지 않은 타입을 파라미터로 처리하고 실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능
  • 타입을 강제하고 컴파일러가 사전에 타입 체크

제네릭 타입


  • 실행 시 타입 지정
    • 해당 타입으로 재정의
  • 결정되지 않은 타입을 파라미터로 가지는 클래스와 인터페이스
package ch13.sec.exam01;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Product <K,M> {
	private K kind;
	private M model;
}

package ch13.sec.exam01;

public class TV {

}
package ch13.sec.exam01;

public class Car {

}

package ch13.sec.exam01;

public class GenericExample {

	public static void main(String[] args) {
		Product<TV, String> product = new Product<>();
		product.setKind(new TV());
		product.setModel("스마트TV");
		
		TV tv = product.getKind();
		String tvModel = product.getModel();
		
		Product<Car, String> product2 = new Product<>();
		product2.setKind(new Car());
		product2.setModel("SUV 자동차");
		
		Car car = product2.getKind();
		String carModel = product2.getModel();
		
		System.out.println(tvModel);
		System.out.println(carModel);
	}

}

출력 결과

스마트TV
SUV 자동차
package ch13.sec.exam02;

public interface Rentable<P>{
	P rent();
}

package ch13.sec.exam02;

public class Car {
	public void run() {
		System.out.println("자동차가 달립니다.");
	}
}

package ch13.sec.exam02;

public class Home {
	public void turnOnLight() {
		System.out.println("전등을 켭니다.");
	}
}

package ch13.sec.exam02;

public class CarAgency implements Rentable<Car>{

	@Override
	public Car rent() {
		return new Car();
	}
	
}

package ch13.sec.exam02;

public class HomeAgency implements Rentable<Home>{

	@Override
	public Home rent() {
		return new Home();
	}
	
}

package ch13.sec.exam02;

public class GenericExample {
	public static void main(String args[]) {
		HomeAgency homeAgency = new HomeAgency();
		Home home = homeAgency.rent();
		home.turnOnLight();
		
		CarAgency carAgency = new CarAgency();
		Car car = carAgency.rent();
		car.run();
	}
}

출력 결과

전등을 켭니다.
자동차가 달립니다.

멀티 스레드


  • 멀티 태스킹은 두 가지 이상의 작업을 동시에 처리
  • 한 프로세스 안에 여러 스레드가 존재

메모


  • Object는 모들 클래스의 최상위 부모 클래스
  • charAt(인덱스)
    • 해당 인덱스의 문자 추출
  • 파일 명이 겹치지 않기 위해 확장자만 남겨두고 파일 명 변경
	// 퀴즈
	String fileName = "2025.04.10_시간표.xlsx";
	// 파일명을 변경 System.currentTimeMillis _> 17.....xlsx
	String newFileName = System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf("."));
	System.out.println(newFileName);
	
	
	
	출력 결과
	
	1744248645683.xlsx
  • 메소드 체이닝
    • 메소드들을 . 으로 연결하여 연쇄적으로 적용하는 방법
package ch12.sec05;

public class StringBuilderEx {

	public static void main(String[] args) {
		String str = "AbcDe        fgHIJKL  MN OP";
		
		System.out.println(str.toUpperCase().replace(" ", "").substring(10).indexOf("L"));
	}

}

출력 결과

1
  • x번째 자리 까지 반올림
    • 10^n 곱하고 (double)10^n으로 다시 나눔
    • java에서 소수점 계산은 명확하지 않음
  • 파일 경로
    • 절대 경로
      • 절대적인 경로
        • Window → 드라이브 명
        • Mac / Linux → /
      • 절대 안 변함
    • 상대 경로
      • 상대적인 경로
        • 내 위치부터 시작
      • 변함
  • 리스트 예제
package ch13;

import java.util.ArrayList;
import java.util.List;

import ch06.sec07.exam01.Car;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

public class GenericEx {
	public static void main(String args[]) {
		// list 인터페이스
		// 배열과 유사 : 여러 값을 저장하는 용도
		// 타입제한 없음, 길이 변경 가능
		List list = new ArrayList();
		
		// 같은 객체
		Order o = new Order();
		o.setNumber("12345");
		list.add(o);
		o.setNumber("12346");
		list.add(o);
		o.setNumber("12347");
		list.add(o);
		
		o = new Order();
		o.setNumber("12345");
		list.add(o);
		o = new Order();
		o.setNumber("12346");
		list.add(o);
		o = new Order();
		o.setNumber("12347");
		list.add(o);
		
//		list.add(new Car("페라리")); // 에러, 강한 타입 체크
				
		for(int i =0; i< list.size(); i++) {
			System.out.println(list.get(i));
			System.out.println(((Order) list.get(i)).getNumber()); // 에러

		}
		
		
	}
}

@Getter
@Setter
@ToString
class Order{
	private String number;
	private String date;
	private int price;
}

출력 결과

페라리, 은색, 250
1
3.14
안녕
모델: 페라리
색깔: 은색
스피드: 250
Order(number=12347, date=null, price=0)
Order(number=12347, date=null, price=0)
Order(number=12347, date=null, price=0)
Order(number=12345, date=null, price=0)
Order(number=12346, date=null, price=0)
Order(number=12347, date=null, price=0)
package ch13;

import java.util.ArrayList;
import java.util.List;

import ch06.sec07.exam01.Car;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

public class GenericEx {
	public static void main(String args[]) {
		// list 인터페이스
		// 배열과 유사 : 여러 값을 저장하는 용도
		// 타입제한 없음, 길이 변경 가능
		List<Order> list = new ArrayList(); // 제네릭 (타입 강제)
		
		// 같은 객체
		Order o = new Order();
		
		o = new Order();
		o.setNumber("12345");
		list.add(o);
		o = new Order();
		o.setNumber("12346");
		list.add(o);
		o = new Order();
		o.setNumber("12347");
		list.add(o);
		
		for(int i =0; i< list.size(); i++) {
			System.out.println(list.get(i).getNumber()); // 사용 가능, 강제 형 변환 불필요
		}
		
		
	}
}

@Getter
@Setter
@ToString
class Order{
	private String number;
	private String date;
	private int price;
}

출력 결과

12345
12345
12346
12346
12347
12347
728x90
반응형