2009-01-23 4 views
15

Tôi đã cố gắng để grok thư viện org.apache.commons.beanutils cho một phương thức/thành ngữ để đánh giá sự bình đẳng tất cả các thuộc tính giữa 2 trường hợp, tức là phương thức equals() chung cho đậu.
Có cách nào đơn giản để thực hiện việc này trong thư viện này không? Hoặc tôi đang đi về điều này một cách sai lầm? Cảm ơn.làm thế nào để so sánh toàn bộ đậu java?

+0

[Thư viện xtendbeans] (http://stackoverflow.com/a/39222891/421602) có thể được quan tâm trong ngữ cảnh này; xem [ví dụ đầy đủ về câu hỏi SO khác này] (http://stackoverflow.com/a/39222891/421602). – vorburger

Trả lời

16

Hãy thử EqualsBuilder.reflectionEquals() trong số commons-lang. EqualsBuilder có một tập hợp các phương thức để bao gồm tất cả các trường, tất cả các trường không phải là tạm thời và tất cả trừ các trường nhất định.

Nếu mọi thứ khác không thành công, mã có thể hoạt động như một ví dụ tốt về cách thực hiện điều này.

+3

Được cảnh báo rằng đây không phải đệ quy - vì vậy nếu bạn có đậu lồng nhau (nghĩa là tài sản của bean là một bean khác), chúng cần phải thực hiện bằng chính họ. 'reflectionEquals' chỉ gọi' equals' trên mỗi thuộc tính, nó không phản ánh vào lớp nữa. – artbristol

+1

@artbristol: +1 nhưng hãy cẩn thận sẽ đệ quy bằng: Bạn có thể dễ dàng bị kẹt trong vòng lặp khi các chu trình hình thành đậu. –

7

Để trả lời câu hỏi của bạn trực tiếp, bạn có thể sử dụng sự phản chiếu để kiểm tra bình đẳng các hạt cà phê. Có một vài snags bạn cần phải nhận thức được.

Có các quy tắc liên quan đến hành vi của equals() và hashcode(). Những quy định này nói về sự đối xứng, consitency và reflexiveness mà có thể khó làm khi bằng phương pháp của bạn cư xử linh hoạt dựa trên các đối tượng khác mà bạn đang đi trong

Thú đọc:. http://www.geocities.com/technofundo/tech/java/equalhash.html

Nói chung, tôi nghĩ rằng bạn nên tạo phương thức hashcode và equals của riêng mình. Có một plugin tốt lành mạnh có thể tự động tạo mã đó cho bạn dựa trên các thuộc tính lớp.

Có nói tất cả điều này, sau đây là một số (kiểu cũ) phương pháp để có được thu khí, setters và tài sản tôi đã viết một thời gian dài trước:

private Map getPrivateFields(Class clazz, Map getters, Map setters) { 
    Field[] fields = clazz.getDeclaredFields(); 
    Map m = new HashMap(); 
    for (int i = 0; i < fields.length; i++) { 
     int modifiers = fields[i].getModifiers(); 
     if (Modifier.isPrivate(modifiers) && !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) { 
      String propName = fields[i].getName(); 
      if (getters.get(propName) != null && setters.get(propName) != null) { 
       m.put(fields[i].getName(), fields[i]); 
      } 
     } 
    } 
    return m; 
} 

Các Getters:

private Map getGetters(Class clazz) { 
    Method[] methods = clazz.getMethods(); 
    Map m = new HashMap(); 
    for (int i = 0; i < methods.length; i++) { 
     if (methods[i].getName().startsWith("get")) { 
      int modifiers = methods[i].getModifiers(); 
      if (validAccessMethod(modifiers)) { 
       m.put(getPropertyName(methods[i].getName()), methods[i]); 
      } 
     } 
    } 
    return m; 
} 

Và Người định cư:

private Map getSetters(Class clazz, Map getters) { 
    Method[] methods = clazz.getMethods(); 
    Map m = new HashMap(); 
    for (int i = 0; i < methods.length; i++) { 
     if (methods[i].getName().startsWith("set")) { 
      int modifiers = methods[i].getModifiers(); 
      String propName = getPropertyName(methods[i].getName()); 
      Method getter = (Method) getters.get(propName); 

      if (validAccessMethod(modifiers) && getter != null) { 
       Class returnType = getter.getReturnType(); 
       Class setType = methods[i].getParameterTypes()[0]; 
       int numTypes = methods[i].getParameterTypes().length; 

       if (returnType.equals(setType) && numTypes == 1) { 
        m.put(propName, methods[i]); 
       } 
      } 
     } 
    } 
    return m; 
} 

Có thể bạn có thể sử dụng tính năng này để tự cuộn.

Chỉnh sửa: ofcourse reflectionbuilder in Aaron Digulla's answer là tốt hơn nhiều so với tiện dụng của tôi.

+0

boolean getters được gọi là isFoo(), do đó, mã sẽ cần tăng cường nhỏ trong getGetters() –

2

Như đã đề cập ở trên, việc triển khai dựa trên sự phản chiếu sẽ làm những gì bạn muốn. Tôi chỉ muốn cảnh báo bạn, phản ánh đó khá tốn kém và việc triển khai như vậy có thể tương đối chậm. Nếu bạn chỉ cần thỉnh thoảng so sánh, bạn sẽ ổn thôi. Tuy nhiên, nếu bạn có các tập dữ liệu khổng lồ và kiểm tra bình đẳng thường xuyên (ví dụ: lọc các bảng lớn), bạn có thể gặp rắc rối.

+0

Điểm tốt thực sự. jguru có một so sánh tốt đẹp trực tuyến: http://www.jguru.com/faq/view.jsp?EID=246569 – Rolf

0

Hoặc, mặc dù không phải là một câu trả lời trực tiếp câu hỏi của bạn, nhưng nó có thể là một câu trả lời cho vấn đề của bạn (tức là loại bỏ các nỗ lực làm mã boilerplate khi là siêu nhanh)

nếu bạn sử dụng Eclipse, bước sau đây sẽ tự động tạo ra các hashCode và equals cho bạn:

Nguồn> Generate hashCode và equals ...

và sau đó chọn các lĩnh vực, đó là siêu hiệu quả!: D

Chúc mừng và tôi hy vọng nó sẽ giúp ai đến đây với mục đích cắt giảm thời gian viết bản mẫu.

PS: Tôi chắc rằng các IDE phổ biến khác phải có các tính năng tương tự.