/** * Created on 10.04.2004 * @author Hue nach Vorlagen von Sid * Zweck: Beispiel für Nutzung des Interfaces Comparable */ package de.fhro.inf.p3.uebung05; import java.util.ArrayList; import java.util.List; import de.fhro.inf.util.Reject; /** * Klasse für Intervalle definiert durch eine untere und obere Grenze. *

* Die Grenzen müssen das Interface Comparable implementieren. * Eine Überprüfung ob die untere Grenze kleiner als die obere * Grenze ist findet nicht statt */ public class Interval { private Comparable lowerBound; private Comparable upperBound; private static final Integer ZERO = new Integer(0); public static final Interval EMPTY = new Interval(ZERO, ZERO); private static Comparable min(Comparable x, Comparable y) { return x.compareTo(y) <= 0 ? x : y; } private static Comparable max(Comparable x, Comparable y) { return x.compareTo(y) > 0 ? x : y; } /** * untere Grenze >= obere Grenze bedeutet leeres Intervall * * @param lowerBound untere Grenze des Intervalls * @param upperBound obere Grenze des Intervalls */ public Interval(Comparable lowerBound, Comparable upperBound) { Reject.ifNull(lowerBound); Reject.ifNull(upperBound); this.lowerBound = lowerBound; this.upperBound = upperBound; } /** * * @param x zu vergleichendes Intervall * @return true falls Intervallgrenzen identisch sind */ public boolean equals(Object x) { if (this == x) return true; if (!(x instanceof Interval)) return false; Interval iv = (Interval) x; return (isEmpty() && iv.isEmpty()) // beide leer || (lowerBound.equals(iv.lowerBound) && upperBound.equals(iv.upperBound)); } /** * @return true, falls lowerBound <= x < upperBound */ public boolean contains(Comparable x) { return lowerBound.compareTo(x) <= 0 && upperBound.compareTo(x) > 0; } /** * @param v das andere Intervall * @return true, wenn this das andere Intervall enthält */ public boolean contains(Interval v) { return v.isEmpty() || (lowerBound.compareTo(v.lowerBound) <= 0 && upperBound .compareTo(v.upperBound) >= 0); } /** * @return Durchschnitt von this und iv. */ public Interval intersection(Interval iv) { return new Interval( max(lowerBound, iv.lowerBound), min(upperBound, iv.upperBound)); } /** * @return true, falls lowerbound >= upperbound */ public boolean isEmpty() { return lowerBound.compareTo(upperBound) >= 0; } /** * * @return eindeutiger Hash-Wert vom Intervall */ public int hashCode() { return isEmpty() ? 0 : lowerBound.hashCode() + upperBound.hashCode(); } public String toString() { return '[' + lowerBound.toString() + ", " + upperBound.toString() + '['; } public List union(Interval iv) { // kommentare in der art: // this u iv // sprich: iv vereinigt mit dem rufenden Intervall // 0 ist leeres Intervall List list = new ArrayList(); Comparable lowerMin = min(this.lowerBound, iv.lowerBound); Comparable upperMax = max(this.upperBound, iv.upperBound); // beide leer -> fall 1 oder zwei greifen mit Liste, die leeres Intervall enthält // fall 1: this = 0 if (isEmpty()) { list.add(iv); } // fall 2: iv = 0 else if (iv.isEmpty()) { list.add(this); } // fall 3: ueberschneidung // 3.1 lower von this kleiner als anderes lower else if (this.contains(iv.lowerBound)) { list.add(new Interval(lowerMin, upperMax)); } else if (iv.contains(this.lowerBound)) { list.add(new Interval(lowerMin, upperMax)); } else if ( !this.contains(iv.lowerBound) && !iv.contains(this.lowerBound) && !this.contains(iv.upperBound) && !iv.contains(this.upperBound)) { list.add(this); list.add(iv); } return list; } }