2012-07-11 12 views
14

Rozważmy prostą klasę:Komparator vs Apache BeanComparator

class Employee { 

String name; 
int sal; 

....//getters and setters 
} 

mogę utworzyć komparatora sortowania na nazwę pola na przykład.

class EmpSortByName implements Comparator<Employee>{ 

@Override 
public int compare(Employee e1, Employee e2){ 
    return e1.getName().compareTo(e2.getName()); 
} 
} 

Jednak patrząc na Apache Commons BeanComparator, sortowania można osiągnąć w następujący sposób:

BeanComparator bc = new BeanComparator("name"); 
Collections.sort(employeeList, bc); 

Zatem stosując BeanComparator, mogę osiągnąć sortowania z minimalnym kodu. Jakie są kompromisy między używaniem Komparatorów i BeanComparators: pod względem wydajności, scenariuszy użycia (sortowanie wielu pól, inne czynniki)?

Rozumiem również, że aby użyć BeanComparator, słoik beanutils musi zostać zaimportowany.

+0

jest minimalny „pozorny” kod. nie zapomnij, że nie wiesz, co robi BeanComparator i może być mniej efektywny niż pierwszy sposób. –

Odpowiedz

19

Komponent BeanComparator używa odbicia, aby uzyskać dostęp do właściwości name i porównać oba obiekty. Pomimo poprawy wydajności odbicia, nadal nie jest tak szybki, jak bezpośredni dostęp do pola. To, czy jest to ważne, zależy od tego, ile razy jest wywoływane w aplikacji i w jakim kontekście.

Innym problemem jest to, że jeśli zmienisz metodę i zmienisz ją na getLastName(), kod wykorzystujący BeanComparator nie zostanie ponownie przeprogramowany, a problem zostanie niezauważony do czasu wykonania (lub czasu testowania urządzenia).

Szczerze mówiąc, wdrażanie komparatora jest tak łatwe, że nie myślę, że używanie refleksji to dobry pomysł. Korzyści z unikania 4 linii banalnego kodu nie wystarczą, aby zrekompensować problemy z wydajnością i konserwacją, które powoduje.

+0

CAŁKOWICIE zgadzam się +1 – MaVRoSCy

+0

@JB Masz rację, z powodu refleksji nastąpi uderzenie wydajności. W jakich okolicznościach powinien być używany BeanComparator? Czy "minimalny" kod jest jedynym powodem? Czy możesz wymyślić jakikolwiek inny powód? –

+3

Nigdy nie miałem potrzeby używać go samodzielnie, ale mogę sobie wyobrazić użycie go w testach jednostkowych lub gdy interfejs użytkownika pozwala dynamicznie wybierać, które obiekty właściwości muszą być sortowane, lub w znaczniku JSP, takim jak displaytag, który musi porównać fasola, nawet nie znając ich typu, bez potrzeby dostarczenia przez programistę kompilatora –

2

także z beancomparator można porównać więcej niż jeden atrybut w łatwy sposób z compareTuple org.ujac.util.BeanComparator beanComparator = new org.ujac.util.BeanComparator(compareTuple); Collections.sort(List,beanComparator);