Acorn academy 12/08 인터페이스 2, 자바의 핵심 클래스

Bae Seong Jun·2023년 12월 8일

Acorn academy

목록 보기
15/70

Acorn academy 12/08

중첩클래스

스마트폰 앱 제작 외에 거의 사용되지 않는다.

member Outer : 클래스의 멤버변수나 메서드처럼 클래스가 정의된 경우이다.
local : Outer 클래스의 특정 메서드 안의 로컬변수처럼 클래스가 정의된 경우
이다.
static : static 키워드를 이용해서 클래스가 정의된 경우이다.
anonymous : 익명 클래스를 이용해서 클래스가 정의된 경우이다.

외부에서의 접근 방식

Outer xxx = new Outer();
Outer.Inner yyy = xxx.new Inner();

아우터에서의 접근 방식
Inner yyy = new Inner();

local Inner 클래스

Outer 클래스의 메서드 안에서 정의한 클래스를 의미한다.
메서드 안에서 정의되었기 때문에 로컬변수처럼 인식된다. 따라서 local inner 클래스는 메서드가 호출될 때 생성되며 메서드가 종료될 때 삭제된다.

static Inner 클래스

Inner 클래스를 정의할 때 static 키워드를 사용하는 형태이다.
일반 Inner 클래스에는 static 변수를 포함할 수 없지만 static Inner 클래스로 정의하면 가능하다. 또한 Outer 클래스를 생성하지 않아도 Inner 클래스를 직접 접근할 수 있다. 반면에 Outer 클래스의 멤버변수는 접근이 불가능하다. 따라서 Inner 클래스에서 static 변수를 포함해야 되는 경우에만 사용하도록 한다.

anonymous Inner 클래스 ( 익명 클래스 )

anonymous Inner 클래스는 local Inner 클래스의 변형된 형태이다. 이름에서 알 수 있듯이 직접 클래스명을 지정하지 않으며 단지 인스턴스의 생성과 메서드 선언만을 정의한다. 일반적으로 인터페이스 또는 추상클래스를 구현하는 클래스로 자주 사용된다. 익명클래스를 함수형 프로그래밍(Functional Programming) 기반으로 확장 표현한 것이 람다식(lambda)이다.

Comparator 인터페이스를 이용한 Array 정렬

java.util.Comparator 인터페이스를 이용하면 배열에 저장된 클래스의 특정 변수 값으로 정렬할 수 있다.

package com.test;

import java.util.Arrays;
import java.util.Comparator;

class Person{
	String name;
	int age;
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}

class PersonComp implements Comparator<Person>{

	@Override
	public int compare(Person o1, Person o2) {
		int result=1;
		if(o1.age >= o2.age) result=-1;
		return result;
	}
	
}

public class Ex07_8 {
	public static void main(String[] args) {
		Person p= new Person("홍길동1", 10);
        Person p1= new Person("홍길동2", 30);
        Person p2= new Person("홍길동3", 40);
        Person p3= new Person("홍길동4", 5);
        Person[] parr = {
        		p, p1, p2, p3
        };
        Arrays.sort(parr, new PersonComp());
        for (Person person : parr) {
			System.out.println(person);
		}
	}
}

자바의 핵심 클래스

< 목차 >
01. 문자열 생성과 관련된 클래스
02. Wrapper 클래스
03. Random 클래스
04. Calendar 및 Date 클래스
05. SimpleDateFormat 클래스
06. enum (열거형 상수)
07. 어노테이션 ( annotation )
08. Scanner API
09. StringTokenizer
10. Arrays API


String 클래스

리터럴을 이용한 방법은 동일한 문자열이 존재한다면 새로 생성되지 않고 재사용된다.
하지만 new를 이용한 방법은 동일한 문자열이 조재해도 매번 새롭게 생성된다.

String 클래스의 가장 큰 특징은 한번 생성된 문자열은 변경되지 않는다는 immutable 불변성 특징이 있다.

String str = new String( “Hello" ); // 1. new 이용
String str2 = "Hello"; // 2. 리터럴 이용

String 클래스의 메소드

package com.test;

public class Ex08_2 {
	public static void main(String[] args) {
		String s = "abcde";
		String s2 = "Hello";
		String s3 = "홍길동/이순신/유관순";
		
		System.out.println("문자열의 길이 : " + s.length());
		System.out.println("문자열 비교 : " + s2.equals("Hello"));
		System.out.println("문자열 비교 : " + s2.equalsIgnoreCase("HELLO"));
		System.out.println("부분열 반환 : " + s.substring(3, 5));
		System.out.println("문자 바꿈 : " + s.replace('a', 'c'));
        System.out.println("소문자로 바꿈: "+s.toLowerCase());
        System.out.println("대문자로 바꿈: "+s.toUpperCase());
        System.out.println("인덱스값의 문자출력(반환값 char) : " + s.charAt(3));
        String t = "  hello  ";
        System.out.println("공백제거: " + t.trim());
        System.out.println("문자열 연결: "+s.concat("test"));
        System.out.println("a에 맞는 인덱스값 출력: "+s.indexOf("a"));
        System.out.println("a에 맞는 인덱스값 출력: "+s.indexOf("x")); //없는 경우 -1 반환
        System.out.println("시작하는 문자열 비교: "+s.startsWith("abc"));
        System.out.println("끝나는 문자열 비교: "+s.endsWith("cde"));
        
        String[] names = s3.split("/");
        for (int i = 0; i < names.length; i++) {
			System.out.println(names[i]);
		}
        
        System.out.println("123문자열로 변환: " + String.valueOf(123));
        System.out.println(123+""); //문자열로 변환
        String result=123+"";
        System.out.println("3.14 문자열로 변환: "+String.valueOf(3.14));
        System.out.println("true 문자열로 변환: "+String.valueOf(true));
        
        String formatString = String.format("이름은 %s, 나이는 %d, 키는 %.2f", "홍길동", 20, 180.2);
        System.out.println(formatString);
        System.out.println(s);

	}
}

StringBuffer 클래스 ( StringBuilder )

앞에서 배운 String 클래스는 '불변성' 특징을 갖기 때문에 문자열 연산시 매우 비효율적으로 메모리를 사용하게 된다.
만약 문자열을 이용한 연산작업이 많은 경우에는 StringBuffer 또는 StringBuilder를 사용할 수 있으며, 두 개의 클래스의 사용법은 거의 유사하고 차이점은 StringBuffer는 thread-safe하지만 무거운 특징을 가지며 StringBuilder는 thread-unsafe하지만 성능이 좋은 특징이 있다.

StringBuffer 클래스의 메서드

length 문자열의 길이를 반환한다.
capacity 초기 버퍼크기를 지정한다.
append 버퍼에 문자열을 추가한다.
insert 버퍼에 문자열을 삽입한다.
delete 버퍼의 문자열을 삭제한다.
toString StringBuffer 객체를 String 객체로 변경한다.

package com.test;

public class Ex08_3 {
	public static void main(String[] args) {
		StringBuffer s = new StringBuffer("Hello");
		s.append(" world");
		System.out.println(s);
		s.insert(5,  "!!! ");
		System.out.println(s);
		s.delete(0, 5);
		System.out.println(s);
		
		String data = s.toString();
		System.out.println(s);
	}
}
  • 참고 : StringBuffer의 append() 메서드와 String의 concat()메서드 그리고 += 연산자를 속도 체크를 해보면 append() > concat() > += 와 같이 append()의 처리속도가 훨씬 빠르다.

아래는 System.currentTimeMillis()를 이용하여 밀리초 단위로 현재시간을 반환받아 3개의 구문의 성능을 테스트하는 구문이다.

public class Test {
	public static void main(String[] args) {
// TODO Auto-generated method stub
		Test t = new Test();
		t.aaa();
		t.bbb();
		t.ccc();
	}

	private void ccc() {
		ong start = System.currentTimeMillis();
		String x = "";
		for (int i = 0; i < 10000; i++) {
			x = x.concat("aaaaaaaaaaaaaaaaa");
		}
		System.out.println("x.length():" + x.length());
		System.out.println("ccc():" + (System.currentTimeMillis() - start));
	}

	private void bbb() {
		long start = System.currentTimeMillis();
		StringBuffer x = new StringBuffer();
		for (int i = 0; i < 10000; i++) {
			x.append("aaaaaaaaaaaaaaaaa");
		}
		System.out.println("x.length():" + x.length());
		System.out.println("bbb():" + (System.currentTimeMillis() - start));
	}

	private void aaa() {
		long start = System.currentTimeMillis();
		String x = "";
		for (int i = 0; i < 10000; i++) {
			x += "aaaaaaaaaaaaaaaaa";
		}
		System.out.println("x.length():" + x.length());
		System.out.println("aaa():" + (System.currentTimeMillis() - start));
	}
}

+ (연결연산자)

Wrapper 클래스

자바에서는 8개의 기본 데이터 타입과 동일한 값을 표현할 수 있는 8개의 클래스들을 제공
하고 ‘Wrapper 클래스’란 이름으로 부른다.

기본데이터 Wrapper
byte java.lang.Byte
short java.lang.Short
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double
char java.lang.Character
boolean java.lang.Boolean

오토방식, 오토언박싱

Object클래스의 배열에 기본데이터타입이 저장될까?
원래는 wrapper 객체로 형변환하여 저장해야함

오토박싱 : 정수를 자동으로 Integer클래스로 변환
오토박싱되어 이제는 자동으로 wrapper 객체로 변환되어 저장된다.

오토언박싱 : 자동 기본형으로 묵시적 형변환

기본형을 Wrapper클래스로, Wrapper 클래스를 기본형으로 변경하기

package com.test;

import java.nio.charset.CodingErrorAction;

public class Ex08_8 {
	public static void main(String[] args) {
		int num = 10;
		@SuppressWarnings("deprecation") //경고제거
		Integer x = new Integer(num);  //wrapper 객체로 명시적 형변환(예전방식)
		Integer x1 = 10; // 자동형변환 (오토박싱)
		// Deprecated: 사용하지 않는 것을 권장
		
		int x2 = x1.intValue(); // Integer 10을 정수로 명시적 형변환 (에전방식)
		System.out.println(x2+10);
		System.out.println(x1+10); //int 형변환이 자동으로 이루어짐 (오토언박싱)
	}
}

Object객체 배열 활용시 기본데이터타입 저장 및 오토언박싱 주의점

package com.test;

public class Test0 {
	public static void main(String[] args) {
		int intnum=10;
		
		// 옛날방식 - 
		Integer it = new Integer(intnum); // 정수를 명시적으로 wrapper클래스로 형변환
		
		//원래 이게 안됨 (자바8이전)
		Object[] arr = {it, intnum, 3.14F}; // 오토박싱 : 정수를 자동으로 Integer클래스로 변환
		
		// 자식클래스로 형변환은 필수 (Object -> 타입에 맞는 객체형으로 변환)
		Integer it0 = (Integer)arr[0];  
		Integer it1 = (Integer)arr[1];
		
		Double it2 = (Double)arr[2];
		
		// 꺼내쓰기 옛날방식 : 기본형으로 명시적 형변
		System.out.println(it0.intValue() + 20);
		
		// 오토언박싱 : 자동 기본형으로 묵시적 형변환
		System.out.println(it0 + 20);

	}
}

Random 클래스

Calendar와 Date 클래스

Date 임포트시 2가지 있어서 주의
Calander.MONTH 는 월을 반환하는데 0~11로 반환해서 주의해야한다.
Calendar.DAY_OF_MONTH 일 반환

다시 한번 읽고 정리

자바 클래스 상수에 대해서 다시 공부
static, 상속부터 정독
Calender 클래스가 날짜를 반환하는 원리 이해

SimpleDateFormat 클래스

앞서 배운 것처럼 Date 클래스안의 많은 메서드가 deprecated 되었기 때문에 필요한 년도
또는 월 데이터만 추출할 수 있는 방법에 많은 제약이 있다. 하지만 java.text.SimpleDateFormat 클래스를 사용하면 java.util.Date 클래스에서 얻은 날
짜데이터를 특정 형식에 맞게 원하는 데이터를 변경하여 출력할 수 있다.

다음은 주요 형식문자이다. 형식 문자 기능
y 년도 표시
M 월 표시
d 일 표시
H 시간(0~23)표시
m 분 표시
s 초 표시
h 시간(1~12)표시
a AM/PM 표시

format()메서드 사용하여 출력포멧 변경

package com.test;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTest2 {
	public static void main(String[] args) {
		Date d = new Date();
		System.out.println(d);
		
		SimpleDateFormat sdf =
				new SimpleDateFormat("yyyy년 MM월 dd일 HH:mm:ss");
		
		String mesg = sdf.format(d);
		System.out.println(mesg);
	}
}

Decimal Format

숫자 포맷 클래스



package com.test;

import java.text.DecimalFormat;
import java.text.ParseException;

public class DecimalFormatTest {
	public static void main(String[] args) throws ParseException {
		DecimalFormat df = new DecimalFormat("$###,###,###");
		String mesg = df.format(987654321);
		System.out.println(mesg);
		
		DecimalFormat df2 = new DecimalFormat("###,###");
		Number xxx = df2.parse("987,654"); //반대로 쉼포 제거
		System.out.println(xxx);
		
		int result = xxx.intValue()+100;  //xxx.biteValue floatValue 등등 을 써서 타입에 맞게 값을 반환받을 수 있다.
		xxx.
		System.out.println(result);
		
	}
}

enum (열거형 상수)

enum은 열거형 상수로 부르며, 데이터가 몇 개의 한정된 상수값으로 구성되어야할 때 주로 사용된다. 아래 코드는 메소드의 매개변수로 3가지 데이터만을 받고싶은 상황에 enum을 이용하여 제한하였다.

package com.test;

public class EnumTest4 {
	
	//상수
	public enum DML { SELECT, INSERT, DELETE}
	
	private void check(DML num) {
		switch (num) {
		case SELECT:
			System.out.println("SELECT");
			break;
		case INSERT:
			System.out.println("INSERT");
			break;
		case DELETE:
			System.out.println("DELETE");
			break;
		default:
			break;
		}
	}
	
	public static void main(String[] args) {
		EnumTest4 et = new EnumTest4();
		et.check(DML.SELECT);
		et.check(DML.INSERT);
		et.check(DML.DELETE);
//		et.check(99);
	}
}

메서드명 설명
name() enum 상수의 이름을 String으로 반환
ordinal() 0부터 시작하는 enum 상수의 index값 반환
values() enum 상수값을 배열로 반환

  • 이전에는 public static final로 지정된 일반적인 상수를 사용하였으나 값 충돌 및 논
    리적인 문제점이 발생되어 enum으로 대체되어 사용된다.

수업듣는 방식 :
설명 읽으며 설명 듣기
이해하면 정리 안되면 기록후에 복습할 때 정리

졸음 쫓는 법

NumberFormat 클래스의getCurrencyInstance()

로컬통화로 숫자를 표시할 수 있음.

package com.test;

import java.text.NumberFormat;
import java.text.ParseException;

public class NumberFormatTest {
	public static void main(String[] args) throws ParseException {
		NumberFormat nf = NumberFormat.getCurrencyInstance();
		
		String mesg = nf.format(987654321);
		System.out.println(mesg);
		
		Number num = nf.parse("₩987,654,321");
		System.out.println(num.intValue()+1);
	}
}

어노테이션

어노테이션은 컴파일러가 검증할 때 필요한 부가 정보 및 메타 데이터를 쉽게 활용할 수 있
도록 JDK 5.X 버전에서 추가된 기능으로, 명시적으로 자바코드에 @시작하는 문자열을 사
용하여 설정한다. 자바코드에서 어노테이션을 설정 가능한 곳은 클래스,변수,메서드에 설정
할 수 있으며 각각 클래스 레벨, 변수 레벨, 메서드 레벨이라고 부른다. 스프링 프레임워크
같은 프로그램에서는 어노테이션을 자바코드만큼 많이 사용하지만, 교재에서는 기본적인 3
가지 어노테이션에 관해서만 살펴보기로 한다.
Java SE 환경에서 기본으로 제공하는 어노테이션은 다음과 같다. § @Override 어노테이션
해당 메서드가 부모 클래스의 메서드를 오버라이딩 한다는 정보를 알려준다. § @Deprecated 어노테이션
해당 클래스 및 변수, 메서드는 과거 버전에서는 사용되었으나 향상된 기능이 추가되어 현
재는 사용하지 않도록 알려준다. § @SuppressWarning 어노테이션
컴파일러에게 경고(warning)정보를 표시하지 않도록 알려준다.

Scanner API

2) java.util.Scanner API 클래스 사용

객체 생성
Scanner scan = new Scanner(System.in);

메서드명 설명
next() 문자열을 공백 기준으로 한 단어씩 반환.
nextLine() 한 줄 전체를 반환
nextInt() int 값으로 받아서 반환
nextDouble() double 값으로 받아서 반환
nextBoolean() boolean 값으로 받아서 반환
close() 자원 반납

☆☆StringTokenizer API

java.util.StringTokenizer는 문자열을 특정 구분자로 분리할 수 있는 클래스로서 String 클
래스의 split() 메서드와 매우 비슷한 기능을 제공한다.(성능이 더 좋다.) 기본 구분자는 공백이다.

객체 생성
StringTokenizer st = new StringTokenizer( "홍길동,이순신,유관순", "," );

메서드명 설명
hasMoreTokens() 남아있는 토큰이 있는지 여부를 boolean 값으로 반환
nextToken() 다음 토큰을 문자열로 반환
countTokens() 사용하지 않고 남아있는 토큰의 개수 반환


자주 쓰는 문자열 함수

toCharArray() : 문자열을 쪼개서 char형의 배열로 반환

아래 코드는
1. toCharArray() 함수로 문자열을 char배열로 만들어 공백을 제외한 문자의 갯수를 구하고
2. StringTokenizer클래스에 문자열과 공백 구분자를 전달하여 객체를 생성.
2-1. 생성된 객체를 이용하여 hasMoreElements(), nextToken() 메소드를 사용하여 while문으로 남은 요소(토큰)이 남아있는 동안 nextToken()으로 구분자로 구분지어진 단어들을 반환받아 출력, 카운팅.

package workshop06.string;

import java.util.Iterator;
import java.util.StringTokenizer;

public class StringTest01 {
	public static void main(String[] args) {
		String str = "I am second to none";
		
		int count1 = 0;
		char [] charArr= str.toCharArray();
		for (char c : charArr) {
			if(c != ' ') {
				System.out.print(c + " ");
				count1++;
			}
		}
		System.out.println("문자개수: " + count1);
		
		StringTokenizer st = new StringTokenizer(str, " ");
//		String[] sa = new String[st.countTokens()];
		int count2 = 0;
		while (st.hasMoreElements()) {
			count2++;
			System.out.print(st.nextToken() + " ");
			
		}
		
		System.out.println("단어개수: " + count2);
		
	}
}
profile
코딩 프로?

0개의 댓글