2019년 8월 9일 금요일

Java Reflection - Attributes




* Java Reflection


자바의 reflection은 자바 런타임 중에 클래스의 멤버들(속성)을 조사할수 있는 굉장히 유용한 도구이다.


참조 문서:https://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html


아래는 클래스에 선언된 메소드들의 리스트를 가져오는 코드이다.

public class Solution {

        public static void main(String[] args){
        
            Class student = Student.class;
            Method[] methods = student.getDeclaredMethods();

            ArrayList methodList = new ArrayList<>();
            for(Method m : methods){
                methodList.add(m.getName());
            }
            Collections.sort(methodList);
            for(String name: methodList){
                System.out.println(name);
            }   
        }
}

2019년 8월 8일 목요일

Java Lambda Expressions (람다 표현식)




* Lambda Expressions (람다 표현식)
 

 익명 클래스(Anonymous class)는 만약 구현해야 할 인터페이스안의 메소드가 단 하나밖에 없는 경우처럼 간단한 경우에 실제 코드상에 해당 메소드를 구현하는 방법은 코드의 가독성이 떨어지고 다루기 불편해 보인다.

 이런 경우에서 자바 8부터 지원되는 람다 표현식은 익명 클래스의 목적은 그대로 사용하면서 간소화한 문법으로 변경된 것이다.

참고 람다표현식 API문서 :https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

아래의 hackerrank 문제는 isOdd, isPrime, isPalindrome 메소드들은 
PerformOperation 객체를 리턴하는데 람다표현식을 이용하여 작성하였다. 

PerformOperation 인터페이스는 구현해야 할 메소드가 한 개밖에 없어 심플하다.
이런 케이스에 람다표현식을 사용하게 되면 가독성이 좋아질 것이다.



interface PerformOperation { 
    boolean check(int a);
}
class MyMath {
    public static boolean checker(PerformOperation p, int num) {
       return p.check(num);
    }

    public static PerformOperation isOdd(){ //짝수, 홀수 찾기
       //람다 표현식을 이용하여 인터페이스의 check 메소드를 구현하고 인스턴스까지 생성할 수 있다. 
       return (int num) -> num % 2 != 0; 
    }

    public static PerformOperation isPrime(){ //소수 찾기
         return (int num) -> {
             for(int i = 2 ;i < Math.sqrt(num) ; i++){
                 if(num % 2 == 0){
                    return false;
                 }else{
                    continue;
                 }
             }
             return true;
             
         };
    }

    public static PerformOperation isPalindrome(){ //앞, 뒤 어느 쪽으로 읽어도 같아지는 숫자 찾기 
         return (int num) -> { 
             int r,sum = 0 , temp;  
             temp = num;
             while(num > 0){
                r = num % 10 ; //나머지, 일의 자리 부터 저장됨
                sum = (sum*10) + r; //거꾸로 뒤집어서 숫자를 만들어감   
                
                num /= 10;
             }

            if(temp == sum)
                return true;
            else
                return false;
             
         }; // 조건식이 여러 줄로 된 경우 중괄호로 묶고 마지막에 세미콜론을 넣는다.
    }
}
public class Solution {

    public static void main(String[] args) throws IOException {
        MyMath ob = new MyMath();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        
        PerformOperation op;
        boolean ret = false;
        String ans = null;
        
        while (T-- > 0) {
            String s = br.readLine().trim();
            StringTokenizer st = new StringTokenizer(s);
            int ch = Integer.parseInt(st.nextToken());
            int num = Integer.parseInt(st.nextToken());
            if (ch == 1) {
                op = ob.isOdd();
                ret = ob.checker(op, num);
                ans = (ret) ? "ODD" : "EVEN";
            } else if (ch == 2) {
                op = ob.isPrime();
                ret = ob.checker(op, num);
                ans = (ret) ? "PRIME" : "COMPOSITE";
            } else if (ch == 3) {
                op = ob.isPalindrome();
                ret = ob.checker(op, num);
                ans = (ret) ? "PALINDROME" : "NOT PALINDROME";
            }
            System.out.println(ans);
        }
    }
}

2019년 8월 1일 목요일

Java MD5, SHA-256 암호화




* MD5
출력값 길이 : 128bit (16진수로 32byte)


* SHA-256
출력값 길이 : 256bit (16진수로 64byte)




public class Solution {

    public static void main(String[] argh) {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        sc.close();
        try {
            //MessageDigest의 인스턴스를 가져올 때 
            //MD5 혹은 SHA-256으로 변경하기만 하면 해당 알고리즘의 해시 값을 얻을 수 있다.
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            
            byte[] digest = md.digest(); //해시된 바이트 배열
            
            for (byte b : digest) {
                System.out.printf("%02x", b);
            }
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

바이트 배열의 요소 각각을 16진수로 변경해야 한다.
System.out.printf("%02x", b);
0 : 자리 수를 맞춰 주기 위한 0 padding 
2 : 너비, 2자리로 고정 
x : 16진수 포맷 출력

2자리로 하는 이유는 해시값이 들어있는 byte 배열의 요소값 하나 하나를 16진수로 변환하면서 4bit까지의 수만 들어있는 경우에는 한 자리가 부족해진다. 
따라서 32byte 고정 길이를 맞춰주기 위해 0을 패딩해주는 것이다.