Java 클래식 사용법 요약

Java프로그래밍에서 언어규범이나 표준 API 문서만으로 배울 수 없는 지식이 있습니다. 본고는 여러분을 위해 나열합니다.
이루다
1. 현재 equals()

class Person {

 String name;

 int birthYear;

 byte[] raw;

 

 public boolean equals(Object obj) {

  if (!obj instanceof Person)

   return false;

 

  Person other = (Person)obj;

  return name.equals(other.name)

    && birthYear == other.birthYear

    && Arrays.equals(raw, other.raw);

 }

 

 public int hashCode() { ... }

}

  • 매개변수는 Object 유형이어야 하며 주변 클래스일 수 없습니다.
  • foo.equals(null)는 false로 돌아가야 하며 NullPointerException을 던질 수 없습니다.(null instanceof 임의의 클래스는false로 되돌아오기 때문에 위의 코드가 실행될 수 있음을 주의하십시오.)
  • 기본 유형역(예를 들어 int)의 비교 사용 = = = 기본 유형수 그룹역의 비교는 Arrays를 사용합니다.equals().
  • equals () 를 덮어쓸 때 hashCode () 를 덮어쓰고 equals () 와 일치해야 합니다.
  • 2、현재 hashCode()
    
    class Person {
    
     String a;
    
     Object b;
    
     byte c;
    
     int[] d;
    
     
    
     public int hashCode() {
    
      return a.hashCode() + b.hashCode() + c + Arrays.hashCode(d);
    
     }
    
     
    
     public boolean equals(Object o) { ... }
    
    }
    
    
  • x와 y 두 대상이 x.equals(y)==true를 가지고 있으면 x.hashCode()=y.hashCode()를 확보해야 합니다.
  • 역명제에 따라 x.hashCode()!=y.hashCode(), 그러면 x.equals(y)==false가 반드시 성립됩니다.
  • 당신은 보증할 필요가 없습니다. x.equals(y)==false시, x.hashCode()!=y.hashCode().그러나 가능한 한 그것을 성립시킬 수 있다면, 이것은 해시표의 성능을 향상시킬 것이다.
  • hashCode()의 가장 간단한 합법적인 실현은 간단하게return0이다.비록 이 실현은 정확하지만, 이것은 HashMap이라는 데이터 구조를 매우 느리게 운행하게 할 것이다.
  • 3. compareTo 구현()
    
    class Person implements Comparable<Person> {
    
     String firstName;
    
     String lastName;
    
     int birthdate;
    
     
    
     // Compare by firstName, break ties by lastName, finally break ties by birthdate
    
     public int compareTo(Person other) {
    
      if (firstName.compareTo(other.firstName) != 0)
    
       return firstName.compareTo(other.firstName);
    
      else if (lastName.compareTo(other.lastName) != 0)
    
       return lastName.compareTo(other.lastName);
    
      else if (birthdate < other.birthdate)
    
       return -1;
    
      else if (birthdate > other.birthdate)
    
       return 1;
    
      else
    
       return 0;
    
     }
    
    }
    
    
    원래 유형의 Comparable가 아닌 범용 버전의 Comparable를 항상 구현합니다.이렇게 하면 코드의 양을 절약하고 불필요한 번거로움을 줄일 수 있기 때문이다.
    결과를 되돌려 주는 마이너스 번호 (마이너스/0/정) 에만 관심을 가지며, 그것들의 크기는 중요하지 않다.
    Comparator.compare () 의 실현은 이것과 유사합니다.
    4. clone 구현()
    
     class Values implements Cloneable {
    
     String abc;
    
     double foo;
    
     int[] bars;
    
     Date hired;
    
     
    
     public Values clone() {
    
      try {
    
       Values result = (Values)super.clone();
    
       result.bars = result.bars.clone();
    
       result.hired = result.hired.clone();
    
       return result;
    
      } catch (CloneNotSupportedException e) { // Impossible
    
       throw new AssertionError(e);
    
      }
    
     }
    
    }
    
    
  • super를 사용합니다.clone()은 Object 클래스가 새 객체를 작성하도록 합니다.
  • 기본 유형 영역은 모두 정확하게 복제되었다.마찬가지로 우리는 String과 Big Integer 등 변하지 않는 유형을 복제할 필요가 없다.
  • 모든 비기본 형식 영역 (대상과 그룹) 을 수동으로 깊이 복사 (deep copy) 합니다.
  • Cloneable 클래스를 실현했습니다. clone () 방법은 영원히 CloneNotSupportedException을 버리지 마십시오.따라서 이 이상을 포착하고 무시하거나 검사되지 않은 이상 (unchecked exception) 으로 포장해야 합니다.
  • Object를 사용하지 않습니다.clone () 방법이 아니라 수동으로 clone () 방법을 실현하는 것은 가능하고 합법적이다.
  • 2. 예방 검사
    1. 예방 검사(Defensive checking) 수치
    
    int factorial(int n) {
    
     if (n < 0)
    
      throw new IllegalArgumentException("Undefined");
    
     else if (n >= 13)
    
      throw new ArithmeticException("Result overflow");
    
     else if (n == 0)
    
      return 1;
    
     else
    
      return n * factorial(n - 1);
    
    }
    
    
  • 입력한 수치가 모두 양수, 충분한 작은 수 등이라고 생각하지 마라.이 조건들을 현저하게 검사해야 한다.
  • 설계가 좋은 함수는 모든 가능성의 입력 값을 정확하게 집행할 수 있어야 한다.모든 상황을 고려하고 잘못된 출력이 발생하지 않도록 해야 한다. (예를 들어 넘침)
  • 2. 예방 검사 대상
    
    int findIndex(List<String> list, String target) {
    
     if (list == null || target == null)
    
      throw new NullPointerException();
    
     ...
    
    }
    
    
  • 대상 매개 변수가 비어 있지 않다고 생각하지 마십시오 (null).이 조건을 현저하게 검사해야 한다.
  • 3. 예방 검출 그룹 인덱스
    
    void frob(byte[] b, int index) {
    
     if (b == null)
    
      throw new NullPointerException();
    
     if (index < 0 || index >= b.length)
    
      throw new IndexOutOfBoundsException();
    
     ...
    
    }
    
    
    그래서 주어진 그룹 인덱스가 경계를 넘지 않는다고 생각하지 마세요.그것을 현저하게 검사해야 한다.
    4. 예방적 검측 수조 구간
    
    void frob(byte[] b, int off, int len) {
    
     if (b == null)
    
      throw new NullPointerException();
    
     if (off < 0 || off > b.length
    
      || len < 0 || b.length - off < len)
    
      throw new IndexOutOfBoundsException();
    
     ...
    
    }
    
    
    주어진 그룹 구간 (예를 들어,off부터,len 요소를 읽는 것) 이 경계를 넘지 않는다고 생각하지 마세요.그것을 현저하게 검사해야 한다.
    셋, 수조
    1. 배열 요소 채우기
    순환 사용:
    
    // Fill each element of array 'a' with 123
    
    byte[] a = (...);
    
    for (int i = 0; i < a.length; i++)
    
     a[i] = 123;
    
    ( ) :
    
    Arrays.fill(a, (byte)123);
    
    
    2. 범위 내의 그룹 요소 복사
    순환 사용:
    
    // Copy 8 elements from array 'a' starting at offset 3
    
    // to array 'b' starting at offset 6,
    
    // assuming 'a' and 'b' are distinct arrays
    
    byte[] a = (...);
    
    byte[] b = (...);
    
    for (int i = 0; i < 8; i++)
    
     b[6 + i] = a[3 + i];
    
    ( ) :
    
    System.arraycopy(a, 3, b, 6, 8);
    
    
    3. 배열 크기 조정
    순환 사용(확장):
    
    // Make array 'a' larger to newLen
    
    byte[] a = (...);
    
    byte[] b = new byte[newLen];
    
    for (int i = 0; i < a.length; i++) // Goes up to length of A
    
     b[i] = a[i];
    
    a = b;
    
    
    순환 사용(규모 축소):
    
    // Make array 'a' smaller to newLen
    byte[] a = (...);
    byte[] b = new byte[newLen];
    for (int i = 0; i < b.length; i++) // Goes up to length of B
     b[i] = a[i];
    a = b;
    
    (우선순위) 표준 라이브러리 사용 방법:
    
    1a = Arrays.copyOf(a, newLen);
    
    
    4. 4바이트 포장(packing)을 하나의 int로 한다
    
    int packBigEndian(byte[] b) {
    
     return (b[0] & 0xFF) << 24
    
        | (b[1] & 0xFF) << 16
    
        | (b[2] & 0xFF) << 8
    
        | (b[3] & 0xFF) << 0;
    
    }
    
     
    
    int packLittleEndian(byte[] b) {
    
     return (b[0] & 0xFF) << 0
    
        | (b[1] & 0xFF) << 8
    
        | (b[2] & 0xFF) << 16
    
        | (b[3] & 0xFF) << 24;
    
    }
    
    
    5. int를 4바이트로 분해(Unpacking)
    
    byte[] unpackBigEndian(int x) {
    
     return new byte[] {
    
      (byte)(x >>> 24),
    
      (byte)(x >>> 16),
    
      (byte)(x >>> 8),
    
      (byte)(x >>> 0)
    
     };
    
    }
    
     
    
    byte[] unpackLittleEndian(int x) {
    
     return new byte[] {
    
      (byte)(x >>> 0),
    
      (byte)(x >>> 8),
    
      (byte)(x >>> 16),
    
      (byte)(x >>> 24)
    
     };
    
    }
    
    
    항상 기호가 없는 오른쪽 이동 조작부호(>>)를 사용하여 위치를 포장(packing)하고 산수 오른쪽 이동 조작부호(>>)를 사용하지 마십시오.
    이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되기를 바랍니다.

    좋은 웹페이지 즐겨찾기