#

Dynamischer Bohnenvergleich

Häufig muss man Datenstrukturen sortieren. Hierbei bedient sich Java der Implementierungen des Interfaces java.util.Comparator. Möchte man ein Array von Objekten nach einer Property sortieren, so kann man den Vergleich dieser implementieren. Oder man bedient sich des Werkzeugkastens Commons-BeanUtils von Apache und schreibt einen PropertyComparator, der die zu vergleichende Property einfach als String entgegen nimmt.

Der folgende Comparator benutzt mehrere Startegien, um die Properties zweier Beans miteinander zu vergleichen. Dabei wird die zu vergleichende Property als String übergeben:

Collections.sort(domainobjects, new BeanPropertyComparator("id"));

Sind die verglichenen Attribute (hier „id“, z. B. Long) ermittelt, kann z. B. ein im Konstruktor mitübergebener Comparator auf die Attributwerte angewendet werden:

Collections.sort(domainobjects, new BeanPropertyComparator("id", new LongComparator()));

Ist kein eigener Comparator für die Attributwerte gegeben, wird zuerst untersucht, ob die Attribute das Interface Comparable implementieren. Ist dies der Fall, wird über dieses Interface verglichen.
Ansonsten wird versucht, einen PropertyEditor zu finden, der den Attributwert in einen String umwandelt um diese per Collator zu vergleichen. Geht dies auch nicht, wird einfach per String.valueOf() eine Stringrepräsentation des Attributwertes erstellt und diese per Collator verglichen.

import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import org.apache.commons.beanutils.PropertyUtils;
import java.text.Collator;
import java.util.Comparator;
 
/**
 * Created 07.08.2008
 * @author M. Serhat Cinar
 */
public class BeanPropertyComparator implements Comparator {
  private Comparator propertyComparator;
  private String property;
  private Collator collator = Collator.getInstance();
 
  public BeanPropertyComparator(String property){
    this.property = property;
  }
 
  public BeanPropertyComparator(String property, Comparator propertyComparator){
    this.property = property;
    this.propertyComparator = propertyComparator;
  }
 
  /**
   * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
   * @throws RuntimeException
   */
  @SuppressWarnings({ "unchecked", "cast" })
  public int compare(Object o1, Object o2) {
    try {
      final Object p1 = PropertyUtils.getProperty(o1, property);
      final Object p2 = PropertyUtils.getProperty(o2, property);
      if (p1==null && p2==null){
        return 0;
      }
      if (p1==null){
        return -1;
      }
      if (p2==null){
        return +1;
      }
      if (propertyComparator!=null){
        return propertyComparator.compare(p1, p2);
      }
      if (p1 instanceof Comparable && p2 instanceof Comparable){
        return ((Comparable) p1).compareTo((Comparable)p2);
      }
      final Object value1 = PropertyUtils.getProperty(o1, property);
      final Object value2 = PropertyUtils.getProperty(o2, property);
      final PropertyEditor pe1 = 
        PropertyEditorManager.findEditor(value1.getClass());
      final PropertyEditor pe2 = 
        PropertyEditorManager.findEditor(value2.getClass());
      String s1, s2;
      if (pe1!=null && pe2!=null){
        pe1.setValue(value1);
        s1 = pe1.getAsText();
        pe2.setValue(value2);
        s2 = pe2.getAsText();
      }
      else{
        s1 = String.valueOf(value1);
        s2 = String.valueOf(value2);
      }
      return collator.compare(s1, s2);
    }
    catch(Exception e){
      throw new RuntimeException(e);
    }
  }
}
Tags:, , , ,

One Response to “Dynamischer Bohnenvergleich” »»

  1. Comment by Stefan | 17:19 10.09.08|X

    Servus Serhat,

    schau mal auf graviton.de.

    Viele Grüße
    Stefan

Leave a Reply »»

Note: All comments are manually approved to avoid spam. So if your comment doesn't appear immediately, that's ok. Have patience, it can take some days until I have the time to approve my comments.