java.util.Objects, java.util.Random, java.util.regex(정규식)

Sangwon Na·2021년 9월 5일
1

1. java.util.Objects

  1. Objects클래스는 모든 메서드가 'static' 입니다.
  2. 객체의 비교나 널 체크(null check)에 유용합니다.

널 체크(null check)

isNull()은 해당 객체가 널인지 확인해서 null이면 true를 반환하고 아니면 false를 반환한다. nonNull()은 isNull()과 반대의 일을 합니다. 즉 !Objects.isnull(obj) 와 같습니다.

null인지 확인하기 위해 isNull()메소드를 호출하고 getUserObject 객체를 매개 변수로 전달합니다. 전달 된 객체가 null이므로 true를 반환합니다.

추가로 requireNonNull()은 해당 객체가 널이 아니어냐 하는 경우에 사용합니다.
만일 객체가 널이면, NullPointerException을 발생시킵니다. 두 번째 매개변수로 지정하는 문자열은 예외의 메시지가 됩니다.

🔽 Objects를 안쓰고 null 검사를 한다면 ↓

void setName(String name) {
	if(name==null) new NullPointerException("name must not be null.");
    this.name = name;
}

🔽 Objects의 requireNonNull() 를 사용한다면 ↓

void setName(String name) {
    this.name = Objects.requireNonNull(name, "name must not be null."); // 두 번째 매개변수 예외메시지
}

객체의 비교

대소비교를 위해 Objects에는 compare()가 추가되었는데, compare()는 두 비교대상이 같으면 0, 크면 양수, 작으면 음수를 반환합니다.

static int compare(Object a, Object b, Comparator c)

// 객체가 같은지 다른지에 대해서는 compare()를 equals()처럼 쓸수도 있습니다.
(compare(x, y)==0) == (x.equals(y))


static import문을 사용했음에도 불구하고 Object클래스의 메서드와 이름이 같은 것들은 충돌이 납니다, 컴파일러가 구별을 못하기 때문이므로, Objects클래스의 이름을 붙여주면 됩니다.

a와 b 두 객체를 비교하는데, equals()가 사용됩니다.
equals()가 Objects클래스에도 있는 이유는, null검사를 하지 않아도 되기 때문입니다.

    if(a!=null && a.equals(b)) {
    	// a가 null인지 반드시 확인해야 한다.
    	}
    
    if(Objects.equals(a, b) {
     	// 매개변수의 값이 null인지 확인할 필요가 없다.
     }

equlas()의 내부에서 널 검사를 하기 때문에 따로 널 검사를 위한 조건식을 따로 넣지 않아도 됩니다.

값이 동일한지 알아보는 equals()와 deepEquals()가 있는데,
a와 b가 모두 널인 경우에는 참을 반환한다는 점을 빼고는 특별한 것이 없습니다.
다만 deepEquals()는 객체를 재귀적으로 비교하기 때문에 다차원 배열의 비교가 가능합니다.
만약 2차원 문자열 배열을 비교할 때, 단순히 equals()를 쓰면 반복문과 함께 써야하는데,
deepEquals()를 쓰면 간단히 끝납니다.


String[][] str2D = new String[][]{{"aaa", "bbb"}, {"AAA","BBB"}};
String[][] str2D2 = new String[][]{{"aaa", "bbb"}, {"AAA","BBB"}};

System.out.println(Objects.equals(str2D, str2D2));	// fasle
System.out.println(Objects.deepEquals(str2D, str2D2));	// true


toString()도 equals()처럼, 내부적으로 널 검사를 합니다.
두번째 메서드는 o가 널일 때, 대신 사용할 값을 지정할 수 있어서 유용합니다.


hashCode()도 내부적으로 널 검사를 한 후에 Object클래스의 hashCode()를 호출합니다.
단, 널일 때는 0을 반환합니다.


2. java.util.Random

난수를 얻는 방법을 생각하면 Math.random()와 Random클래스를 사용하는 방법이 있습니다.
다만 대부분의 경우 Math.random()만 사용해도 난수를 얻는데 별 어려움이 없기 때문에 가능하면 Random보다는 Math.random()을 권장합니다.
Math.randome()과 Random의 가장 큰 차이점은, 종자값(seed)을 설정할 수 있다는 것입니다.
따라서 종자값이 같은 Random인스턴스들은 항상 같은 난수를 같은 순서대로 반환합니다.

Random rand = new Random(1); // Random(long seed)로 종자값을 매개변수로 받는다.
Random rand2 = new Random(1); // 같은 종자값을 전달하면, 둘은 같은 랜덤값을 줍니다

System.out.println("= rand =");
for(int i=0; i < 3; i++)
	System.out.println(i + ":" + rand.netxInt());
    
System.out.println("= rand2 =");
for(int i=0; i < 3; i++)
	System.out.println(i + ":" + rand.netxInt());
    
    // 출력결과  rand.nextInt(10) -> 0~9까지 랜덤
= rand =
0: -1155869325
1: 431529176
2: 1761283685

= rand2 =
0: -1155869325
1: 431529176
2: 1761283685

생성자 Random()은 아래와 같이 종자값을 nonoTime()로 하기 때문에 실행할 때마다 얻는 난수가 달라집니다.


3. java.util.regex

정규식이란 텍스트 데이터 중에서 원하는 조건(패턴, pattern)과 일치하는 문자열을 찾아내기 위해 사용하는 것으로 미리 정의된 기호와 문자를 이용해서 작성한 문자열을 말한다.

    static public void main(String[] args) {
        String[] data = {"bat", "baby", "bonus", "c", "cA", "ca", "co", "c.", "c0", "c#", "car", "combat", "count", "date", "disc"};
        String[] pattern = {".*", "c[a-z]*", "c[a-z]", "c[a-zA-z]", "c[a-zA-Z0-9]", "c.", "c.*", "c\\.", "c\\w", "c\\d", "c.*t", "[b|c].*", ".*a.*", ".*a.+", "[b|c].{2}]"};

        for (int x = 0; x < pattern.length; x++) {
            Pattern p = Pattern.compile(pattern[x]);
            System.out.print("Pattern: " + pattern[x] + " 결과: ");
            for (int i = 0; i < data.length; i++) {
                Matcher m = p.matcher(data[i]);
                if(m.matches())
                    System.out.print(data[i] + ", ");
            }
            System.out.println();   // 정규표현식 하나씩 적용후 개행처리
        }
    }
    

    static public void main(String[] args) {
        String source = "HP:011-1234-5678, HOME:02-123-4567";
        String pattern = "(0\\d{1,2})-(\\d{3,4})-(\\d{4})";

        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(source);

        int i = 0;
        while(m.find()) {
            System.out.println(++i + ": " + m.group() + " -> " + m.group(1) + ", " + m.group(2) + ", " + m.group(3));
        }
     }

group() 또는 group(0)은 그룹으로 매칭된 문자열을 전체를 나누어지지 않은 채로 반환한다.
find()는 주어진 소스 내에서 패턴과 일치하는 부분을 찾아내면 true를 반환하고 찾지 못하면 false를 반환한다. find()을 호출해서 패턴과 일치하는 부분을 찾아낸 다음, 다시 find()를 호출하면 이전에 발견한 패턴과 일치하는 부분의 다음부터 다시 패턴매칭을 시작한다.

profile
나상원의 LOG

1개의 댓글