달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
2010. 12. 8. 11:08

이진소수점 계산할 때.. Study/Java2010. 12. 8. 11:08

자바퍼즐러 퍼즐2

결론 : 정확한 답을 요구하는 곳에서는 float 타입과 double 타입을 피하고 금전 계산에서는 int,long 또는 BigDecimal

을 사용할 것.

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

System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.10"));
}

위의 식에서 System.out.println(2.00 - 1.10) 을 그대로 할 경우 이진부동소수점 계산이 되기 때문에..

근사값으로 계산되기 때문에 BigDecimal을 이용함.

※ BigDecimal(double)이 아닌 BigDecimal(String) 생성자를 사용하자.
:
Posted by 유쾌한순례자
2010. 11. 16. 17:54

compareTo Study/Java2010. 11. 16. 17:54

대체로 정렬을 할 때 사용하는 것으로 사용법은 obj.compareTo(obj2) 이런식이고.

양수일땐 obj > obj2
음수일땐 obj2 < obj
0일땐 obj = obj2

.... 이제 교재로.

:
Posted by 유쾌한순례자
equals 메소드를 오버라이드 하면 hashCode 도 오버라이드 해줘야 주소값이 일치한다.

@Override
    public int hashCode(){
     return answer.hashCode();
    }

해주었더니 주소값이 일치함을 알 수 있었다.
:
Posted by 유쾌한순례자
급식신청시스템을 완성하고 베타 테스트를 끝내고 본격적으로 운영에 들어갔다.

3~4일 잘 운영되고 있었는데 어느 날 한 분에게 전화가 왔다.

분명 신청했는데 자신의 이름이 명단에 빠져서 식사를 못했다는 것이었다.

문의에 대해서 접수를 하고 확인하기 시작했다.

for문으로 10000번 돌려서 신청하게도 해보고 다른 pc들에서도 신청하게 해보았는데 아무런 문제가 없었다.

단순 실수였겠거니 하였는데 가끔씩 누락된다고 하는 분들이 발생하였고 오차 돈이 커지면서 문제가 될 소지가 있었다.

일단 급식신청시스템을 1주일간 중단하고 원인에 대해서 분석하기 시작했다.

확인결과 a라는 사람과 b라는 사람이 동시에 신청하게 되면 a라는 사람만 신청이 되는 것이었다.

신청 부분을 동기화로 처리한 뒤 재운영을 하였다.

현재까지는 문제점이 발생되지 않는다.(약 6개월) 이것으로 해결이 된 건지는 아직 불명확하지만 거의 해결이라고 봐도

될 것 같다.
:
Posted by 유쾌한순례자
어렵게 꼬아놔서 뭔 소리인지 잘 몰랐는데 그냥 요약된 부분만 보니깐 알겠더라..

한마디로 수학 으로 생각하면 된다.

재귀적 : a=a
대칭적 : a=b  b=a
이행적 : a=b  b=c  a=c
일관적 : a=b 같은 상태에서 a와 b의 값이 변함이 없다면 항상 a=b

개인적으로 자주 겪었던 대칭적 부분만 일단 자세히 짚어보았다.

equals 오버라이딩 공부할때 작성했던 소스를 책 예제로 약간 개조해보자면

@Override
    public boolean equals(Object obj) {
        if((obj instanceof Quiz)&& obj != null ) {
            return answer.equalsIgnoreCase(((Quiz)obj).answer);
        }
        if((obj instanceof String) && obj != null){
            return answer.equalsIgnoreCase((String)obj);
        }
        return false;
    }

이렇게 한다음 q1,q2를 이런식으로 선언했다.

Quiz q1 = new Quiz("asd");
String q2 = "Asd"

그 다음 q1.equals(q2) 결과와 q2.equals(q1)의 결과를 비교했다.

첫번째는 같다. 두번째는 다르다 가 나왔다.

a=b b=a 라는 대칭적 계약의 위반이다. Quiz의 equals 메소드는 일반 문자열을 처리하고 있는 반면 String equals 메소드는

대소문자를 구분하지 않는 문자열을 인식하지 못하는 것이다.

이것을 고쳐보자면


@Override
    public boolean equals(Object obj) {
        return obj instanceof Quiz && ((Quiz)obj).answer.equalsIgnoreCase(answer);
    }

두 조건다 false 를 반환하게 된다.

이 예제의 의미를 잘 몰라서 자초스 뉴와이 님의 도움으로 알게 되었다.

뉴와이 님의 답변 전문

책 내용대로 라도 false false를 반환하게 설계하라고 추천하고 있는겁니다.

책에서 equlas()의 대칭성을 설명하는 부분이었고,
이전의 CaseInsensitiveString클레스에서
String클레스 형의 객체와 비교 가능하게 설계되어있을 겁니다.
하지만 String클레스에서 CaseInsensitiveString형의 비교 불가능하게 되어있죠..

ex)
CaseInsensitiveString a = new CaseInsensitiveString("Polish");
String b = "polish";

a.equals(b); //true
b.equals(a); //false
여서 대칭성의 문제로
CaseInsensitiveString에서
String형의 객체와의 비교처리를 지원하지 말라고 추천하는 내용입니다.

a에서의 equlas()만 지원하는 일방적인 equals 형태이죠.
이걸 방지하자는 내용이죠...

:
Posted by 유쾌한순례자
2010. 11. 11. 22:11

equals 메소드를 오버라이딩 하기. Study/Java2010. 11. 11. 22:11

그냥 String a = "aaa";
String b="aaa";

a.equals(b) 는 같다고 나오지만

String a = new String("aaa");
String b = new String("aaa");

a.equals(b) 는 false를 반환한다.

이럴 때에는 equals 메소드를 오버라이딩 해준다.

class Quiz {
    private final String answer;
   
    public Quiz(String answer){
     this.answer=answer;
    }
 
    @Override
    public boolean equals(Object obj) {
        if((obj instanceof Quiz)&& obj != null ) {
            return answer ==((Quiz)obj).answer;  
        } else {
            return false;
        }
    }
   
}

public class eqtest {
    public static void main(String[] args)
    {
    
     Quiz q1 = new Quiz("테스트중입니다");
     Quiz q2 = new Quiz("테스트중입니다");

      if(q1==q2){
         System.out.println("같다");
      }else{
         System.out.println("다르다");

      if(q1.equals(q2)){
         System.out.println("같다");
      }else{
         System.out.println("다르다");
      }
   }
}
결과

다르다
같다

이제 Effective JAVA 에 항목 8 'equals 메소드를 오버라이딩 할 때는 보편적 계약을 따르자' 참고해서 공부해야겠다.
:
Posted by 유쾌한순례자