1 package org.thegalactic.util; 2 3 /* 4 * ComparableSet.java 5 * 6 * Copyright: 2010-2015 Karell Bertet, France 7 * Copyright: 2015-2016 The Galactic Organization, France 8 * 9 * License: http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html CeCILL-B license 10 * 11 * This file is part of java-lattices. 12 * You can redistribute it and/or modify it under the terms of the CeCILL-B license. 13 */ 14 import java.util.SortedSet; 15 import java.util.TreeSet; 16 17 /** 18 * This class gives a minimal representation of a comparable set where sets are 19 * compared using the lectic order. 20 * 21 * This class extends class `TreeSet`, implements class `Comparable` and 22 * provides a {@link #compareTo} method that implements the lectic order between 23 * two sets. 24 * 25 * Therefore, a comparable set can be stored in a sorted collection, and in 26 * particular in a sorted set where set operations are provided. 27 * 28 * The lectic order extends the inclusion, and is defined only for comparable 29 * elements, i.e. elements that can be sorted, as follows: 30 * 31 * "a set `A` is smaller than a set `B` iff there exists an element in `B\A` 32 * such that any smaller element belonging to `A` also belongs to `B`." 33 * 34 * @param <E> Element type 35 * 36 * @todo Check if this class is correctly used (performance). Overload 37 * modification method to compute the hashCode only once. 38 * 39 * ![ComparableSet](ComparableSet.png) 40 * 41 * @uml ComparableSet.png 42 * !include resources/org/thegalactic/util/ComparableSet.iuml 43 * 44 * hide members 45 * show ComparableSet members 46 * class ComparableSet #LightCyan 47 * title ComparableSet UML graph 48 */ 49 public class ComparableSet<E extends Comparable> extends TreeSet<E> implements Comparable<ComparableSet>, Cloneable { 50 51 /* 52 * ------------- CONSTRUCTORS ------------------ 53 */ 54 /** 55 * Constructs a new and empty ComparableSet. 56 */ 57 public ComparableSet() { 58 super(); 59 } 60 61 /** 62 * Constructs a new ComparableSet with the set from the specified set. 63 * 64 * @param set a comparable set 65 */ 66 public ComparableSet(final SortedSet<E> set) { 67 super(set); 68 } 69 70 /* 71 * --------------- OVERLAPPING METHODS ------------ 72 */ 73 /** 74 * Returns a clone of this component. 75 * 76 * @return a clone of this component. 77 */ 78 @Override 79 public ComparableSet clone() { 80 return (ComparableSet) super.clone(); 81 } 82 83 /** 84 * Compares this component with those in parameter according to the lectic 85 * order. 86 * 87 * The lectic order defines a sort on sets of elements extending the 88 * inclusion order as follows: 89 * 90 * A set `A` is smaller than a set `B` iff there exists an element in `B\A` 91 * such that any smaller element belonging to A also belongs to B. The 92 * result is 93 * 94 * - zero if the identifiers are equal; 95 * - 1 if this component's identifier is greater; 96 * - -1 otherwise. 97 * 98 * This comparison method is needed to define a natural and total sort on a 99 * sets. 100 * 101 * It allows to use sets of this class in a sorted collection 102 * 103 * @param set the specified element to be compared with this component 104 * 105 * @return a negative integer, zero, or a positive integer as this component 106 * is less than, equal to, or greater than the specified object according to 107 * the lectic order. 108 * 109 * @todo Is this correct? (see test) 110 */ 111 public int compareTo(final ComparableSet set) { 112 113 int cmp; 114 115 // case of equality between this component and object 116 if (this.equals(set)) { 117 cmp = 0; 118 } else { 119 // computes index i of the first element in set minus this 120 // if i doesn't exist, then this component is not smaller than the set by lectic order 121 final TreeSet<Comparable> setMinusThis = new TreeSet(set); 122 setMinusThis.removeAll(this); 123 if (setMinusThis.isEmpty()) { 124 cmp = 1; 125 } else { 126 final Comparable i = setMinusThis.first(); 127 // compute this inter {1, ..., i-1} 128 final TreeSet setAiMinus1 = new TreeSet(); 129 for (final Object c : this) { 130 if (i.compareTo(c) > 0) { 131 setAiMinus1.add(c); 132 } 133 } 134 // compute set inter {1, ..., i-1} 135 final TreeSet setBiMinus1 = new TreeSet(); 136 for (final Object c : set) { 137 if (i.compareTo(c) > 0) { 138 setBiMinus1.add(c); 139 } 140 } 141 // if setAiminus1 and setBiminus1 are equal then this component is smaller than B by lectic order 142 if (setAiMinus1.equals(setBiMinus1)) { 143 cmp = -1; 144 } else { 145 cmp = 1; 146 } 147 } 148 } 149 return cmp; 150 } 151 }