728x90

Overriding

  • 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의하여 사용.
  • 상속의 관계에 있는 클래스 간에 하위 클래스가 상위 클래스와 완전 동일한 메소드를 덮어쓴다.
  • 이름과 반환형이 같으면서 매개변수의 개수와 타입까지 같은 메소드
  • 자식 클래스는 부모 클래스의 private 멤버를 제외한 모든 메소드를 상속 받는다.

 

Overriding 조건

  • 오버라이딩이란 메소드의 동작만을 재정의 하는 것. 메소드의 선언부는 기존 메소드와 완전히 동일해야 한다.
  • 메소드의 반환 타입은 부모 클래스의 반환 타입으로 변환할 수 있는 타입이라면 변경 가능.
  • 부모 클래스의 메소드보다 접근 제어자를 더 좁은 범위로 변경할 수 없다.
  • 부모 클래스의 메소드보다 더 큰 범위의 예외를 선언할 수 없다.

 

Overriding 예제

class Parent {
    void display() { System.out.println("부모 클래스의 display() 메소드입니다."); }
}

class Child extends Parent {
    void display() { System.out.println("자식 클래스의 display() 메소드입니다."); }
}
 

public class Test {
    public static void main(String[] args) {

        Parent pa = new Parent();

        pa.display();

        Child ch = new Child();

        ch.display();

        Parent pc = new Child();

        pc.display(); 
        
    }
}

// 부모 클래스의 display() 메소드입니다.
// 자식 클래스의 display() 메소드입니다.
// 자식 클래스의 display() 메소드입니다.
728x90
728x90

Immutable Object

  • 불변객체란 한번 객체가 생성되면 그 상태를 바꿀 수 없는 객체
  • JAVA의 대표적인 불변객체는 String이 있다.

 

JAVA의 String

// ex)
String str = "abc";
str = "def";

위 예제는 str변수의 값이 바뀐 것이라고 착각하기 쉽다.

하지만 "def"라는 새로운 객체가 생성되고 str변수가 "def"를 참조 한 것이다.

원래 "abc"객체의 값은 그대로 "abc"로 남아있다. 더이상 참조되지 않는 것이다.

불변객체는 new 인스턴스로 재할당하는 것 외에는 값을 바꿀 수 없다.

 

Immutable Object 정의 방법

  • "setter" 메소드를 사용하지 않는다.
  • 모든 필드(field)를 final, private 사용.
  • 상속 받는 subclass가 해당 메소드를 오버라이딩하게 하지 않는다.(간단한 방법은 final 클래스로 선언)
  • 인스턴스 필드가 가변 객체에 포함되어 참조 되면 해당 객체가 변하게 하지 말 것.(가변 객체에 제공 하지 않는다)

 

Immutable Object 장단점

장점

  • 불변이기에 객체에 대한 신뢰도가 높아진다(객체가 안전하다).
  • 생성자, 접근 메소드에 대한 방어 복사가 필요 없다.
  • 멀티 스레드 환경에서 동기화 처리 없이 객체를 공유 할 수 있다.

단점

  • 객체가 가지는 값마다 새로운 객체가 필요하다.
  • 메모리 누수와 새로운 객체를 계속 생성하기 때문에 성능 저하를 발생시킬 수 있다.
728x90
728x90

String, StringBuilder, StringBuffer 차이점

  • String 객체는 한번 생성되면 할당된 공간이 변하지 않는다.
  • String 객체는 concat 또는 + 연산자를 통해 기존 생성된 String 객체 문자열에 다른 문자열을 붙여도 기존 문자열에 새로운 문자열을 붙이는 것이 아닌, 새로운 String 객체를 만든 후 문자열을 저장하고 그 객체를 참조한다.
  • 즉 String 객체는 concat 또는 + 연산자를 많이 사용 할 수록 String 객체의 수가 늘어나기 때문에 성능이 느려진다.
  • StringBuffer나 StringBuilder의 경우 객체의 공간이 부족해 지는 경우 버퍼의 크기를 유연하게 늘려준다.
  • 이러한 특징을 String은 불변(immutable)하고 StringBuffer와 StringBuilder는 가변(mutable)하다.

 

StringBuilder, StringBuffer 같은점, 차이점

같은점

  • StringBuilder와 StringBuffer는 둘 다 크기가 유연하게 변하는 가변적인 특성을 가진다.
  • 제공하는 메소드도 같고 사용하는 방법도 동일하다.

 

차이점

  • 두 클래스는 동기화 지원의 유무가 다르다.
  • StringBuffer는 각 메소드 별로 synchronized keyword가 존재하여 멀티 스레드 상태에서 동기화 지원.
  • StringBuilder는 단일 스레드 환경에서만 사용하도록 설계되어 있다.
  • StringBuffer는 멀티 스레드 환경에서도 안전하게 동작할 수 있다.

 

정리

  • String
    • 짧은 문자열을 더할 경우
    • 문자열 연산이 적고 멀티 스레드 환경일 경우
  • StringBuffer
    • 스레드에 안전한 프로그램이 필요하거나, 개발 중인 시스템의 부분이 스레드에 안전하지 모를 경우
    • 문자열 연산이 많고 멀티 스레드 환경일 경우
  • StringBuilder
    • 스레드에 안전한지 여부가 전혀 관계 없는 프로그램을 개발할 경우
    • 문자열 연산이 많고 단일 스레드이거나 동기화를 고려하지 않아도 되는 경우

 

728x90
728x90

StringBuilder

  • StringBuilder는 문자열을 변경하거나 이어붙이는 경우 추가 메모리 생성 없이 기존 문자열이 확장.
  • String과 다르게 문자열이 빈번하게 변경될 때 사용하면 성능이 좋다.
  • StringBuilder는 멀티쓰레드 환경에서 문자열의 안전한 변경을 보장해주지 않는 특징이 있다.
  • 즉, 여러 쓰레드가 문자열에 동시 접근, 변경이 이루어지면 수행결과가 올바르지 않는 것을 의미.

 

StringBuilder 사용법

public class Main
{
    public static void main(String[] args)
    {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("문자열 ").append("연결");
        // String str = stringBuilder; // String에 StringBuilder를 그대로 넣을 순 없다. 
        String str = stringBuilder.toString(); // toString()사용
        // 두 println()은 같은 값을 출력한다
        System.out.println(stringBuilder);
        System.out.println(str);
    }
}

 

StringBuilder 주요 메소드

  • append() - 문자열 추가
  • capacity() - 현재 char[] 배열이 가진 사이즈 정보를 반환
  • delete() - 매개변수로 전달받은 인덱스 사이의 문자열 제거
  • deleteCharAt() - 특정 인덱스의 한 문자만 삭제
  • insert() - 특정 위치에 문자열 삽입
  • reverse() - 문자열을 거꾸로 뒤집어 반환
  • setCharAt() - 특정 위치의 문자 변경
  • setLength() - 문자열 길이 조정
  • trimToSize() - 문자열이 저장된 char[] 배열 사이즈를 현재 문자열 길이와 동일하게 조정

 

728x90
728x90

contains()

  • boolean contains(CharSequence s)
  • contains()는 대상 문자열에 특정 문자열이 포함되어 있는지 확인
  • 대소문자를 구분
  • 특정 문자열이 포함되어 있다면 true, 없다면 false 반환

 

contains() 예제

public class Main {
	public static void main(String[] args) {
        String str = "Hello World";

        System.out.println(str.contains("Hello")); // true  
        System.out.println(str.contains("hello")); // false  
        System.out.println(str.contains(" Hello")); // false  
        System.out.println(str.contains(" World")); // true  
        System.out.println(str.contains("Hello World")); // true  
        
	}
}
728x90
728x90

compareToIgnoreCase()

  • compareToIgnoreCase()는 대소문자 구분 없이 두 문자열을 비교.
  • compareTo()와 동일한 결과 값을 리턴
  • 이전글 compareTo() 참고
public class Main {
	public static void main(String[] args) {
        String str = "abcd";

        System.out.println( str.compareToIgnoreCase("AB") ); // 2 
        System.out.println( str.compareToIgnoreCase("zefd") ); // -25 
        System.out.println( str.compareToIgnoreCase("ABFe") ); // -3        
        System.out.println( str.compareToIgnoreCase("abcd") ); // 0
        System.out.println( str.compareToIgnoreCase("ABCD") ); // 0

	}
}
728x90
728x90

compareTo()

// 숫자형 비교
int compareTo(NumberSubClass referenceName)

// 문자열 비교
int compareTo(String anotherString)
  • compareTo()는 두개의 값을 비교하여 int 값으로 반환해 준다.
  • compareTo()는 위에서 적어둔 것 처럼 문자열 비교와 숫자 비교 두가지 방식이 존대한다.

 

숫자형 비교

  • 숫자형 비교는 단순히 크다(1), 같다(0), 작다(-1)을 결과값으로 리턴한다.
  • 숫자형 비교는 Byte, Double, Integer, Float, Long, Short 등을 비교 할 수 있다.
  • int로 선언해서 사용할 때는 Integer.compare(기준값, 비교값)으로 사용.
public class Main {
	public static void main(String[] args) {
    
		Integer a = 3; 
		Integer b = 4; 
		Double c = 1.0; 
		int x = 5;
		int y = 6;
        
		System.out.println( a.compareTo(b) ); // -1 
		System.out.println( a.compareTo(3) ); // 0 
		System.out.println( a.compareTo(2) ); // 1 
		System.out.println( c.compareTo(2.7) ); // -1
		System.out.println(Integer.compare(x, y)); // -1

	}
}

 

문자열 비교

  • 문자열 비교의 경우 같은 문자열은 숫자와 동일하게 0을 리턴
  • 문자열 비교는 숫자형 비교와 결과값이 다르므로 예제로 설명

 

비교 대상에 동일한 문자열이 포함 되어 있는 경우

public class Main {
	public static void main(String[] args) {
        String str = "abcd";

        System.out.println( str.compareTo("abcd") );  // 0 (같은 문자열은 0을 리턴)
        System.out.println( str.compareTo("ab") );  //  2
        System.out.println( str.compareTo("a") );  //  3
        System.out.println( str.compareTo("c") );  //  -2      

	}
}

 

str.compareTo("ab") / str.compareTo("a")

- 기준값의 앞자리부터 일치하는 문자열이 포함된 경우 (기준문자열길이-비교대상문자열길이) 리턴
ex) "abcd"(4) - "ab"(2) = 2  / "abcd"(4) - "a"(1) = 3 리턴

 

str.compareTo("c")

- 비교가 불가능한 지점의 각 문자열의 아스키값을 기준으로 비교 아스키 코드값의 차이값을 리턴

* compareTo는 같은 위치의 문자를 비교한다.

예제에서는 첫번째 위치에서 비교가 실패했기 때문에 "a"와 "c"의 차이값을 리턴한다. (a=97,c=99 / a-c=-2)

 

비교 대상과 문자열이 전혀 다른 경우

public class Main {
	public static void main(String[] args) {
        String str = "abcd";

        System.out.println( str.compareTo("zefd") ); // -25 
        System.out.println( str.compareTo("ABCD") ); // 32

	}
}

 

str.compareTo("zefd") 

- 위와 같은 논리로 첫 문자부터 다르므로 "a"와 "z"의 아스키코드 차이값 리턴

ex) a=97, z=122 / 97-122=-25

str.compareTo("ABCD")

- "a"와 "A"의 아스키코드 차이값 리턴

ex) a=97, A=65 / 97-65=32

728x90
728x90

rint()

rint()는 정수 값에 가장 가까운 매개 변수를 반환

public static double rint(double d)

 

rint() 예제

public class Main{
	public static void main(String args[]){
		double num1 = 100.675;
		double num2 = 10.400;
		double num3 = 99.200;

		System.out.println(Math.rint(num1)); // 101.0
		System.out.println(Math.rint(num2)); // 10.0
		System.out.println(Math.rint(num3)); // 99.0
	}
}
728x90

+ Recent posts