Partial ordered Comparator

后端 未结 6 1477
灰色年华
灰色年华 2020-12-18 22:35

How to implement java.util.Comparator that orders its elements according to a partial order relation?

For example given a partial order relation a

相关标签:
6条回答
  • 2020-12-18 22:50

    The problem is that, when you have incomparable elements, you need to fall back to something cleverer than comparing hash codes. For example, given a partial order {a < b, c < d}, the hash codes could satisfy h(d) < h(b) < h(c) < h(a), which means that a < b < c < d < a (bold denotes tie broken by hash code), which will cause problems with a TreeMap.

    In general, there's probably nothing for you to do except topologically sort the keys beforehand, so some details about the partial orders of interest to you would be welcome.

    0 讨论(0)
  • 2020-12-18 22:51

    If a < b and b < c implies a < c, then you have made a total ordering by using the hashCodes. Take a < d, d < c. The partial order says that b and d not necessarily are ordered. By introducing hashCodes you provide an ordering.

    Example: is-a-descendant-of(human, human).

    Adam (hash 42) < Moses (hash 17), Adam < Joe (hash 9)
    

    Implies

    Adam < Joe < Moses
    

    A negative example would be the same relation, but when time travel allows being your own descendant.

    0 讨论(0)
  • 2020-12-18 22:54

    It seems to be more of an answer than a comment so I'll post it

    The documentation says:

    It follows immediately from the contract for compare that the quotient is an equivalence relation on S, and that the imposed ordering is a total order on S."

    So no, a Comparator requires a total ordering. If you implement this with a partial ordering you're breaching the interface contract.

    Even if it might work in some scenario, you should not attempt to solve your problem in a way that breaches the contract of the interface.

    See this question about data structures that do fit a partial ordering.

    0 讨论(0)
  • 2020-12-18 23:00

    Any time I've tried using hash codes for this sort of thing I've come to regret it. You will be much happier if your ordering is deterministic - for debuggability if nothing else. The following will achieve that, by creating a fresh index for any not previously encountered Item and using those indices for the comparison if all else fails.

    Note that the ordering still is not guaranteed to be transitive.

    class ItemPartialOrderComperator implements Comparator<Item> {
        @Override
        public int compare(Item o1, Item o2) {
            if(o1.equals(o2)) {
                return 0;
            }
            if(o1.before(o2)) {
                return -1;
            }
            if(o2.before(o1)) {
                return +1;
            }
            return getIndex(o1) - getIndex(o2);
        }
    
        private int getIndex(Item i) {
            Integer result = indexMap.get(i);
            if (result == null) {
                indexMap.put(i, result = indexMap.size());
            }
            return result;
        }
    
        private Map<Item,Integer> indexMap = new HashMap<Item, Integer>();
    }
    
    0 讨论(0)
  • 2020-12-18 23:03

    When one item is neither "before" nor "after" another, instead of returning a comparison of the hashcode, just return 0. The result will be "total ordering" and "arbitrary" ordering of coincident items.

    0 讨论(0)
  • 2020-12-18 23:06

    In jdk7, your object will throw runtime exception :

    Area: API: Utilities Synopsis: Updated sort behavior for Arrays and Collections may throw an IllegalArgumentException Description: The sorting algorithm used by java.util.Arrays.sort and (indirectly) by java.util.Collections.sort has been replaced.
    The new sort implementation may throw an IllegalArgumentException if it detects a Comparable that violates the Comparable contract. The previous implementation silently ignored such a situation. If the previous behavior is desired, you can use the new system property, java.util.Arrays.useLegacyMergeSort, to restore previous mergesort behavior.

    Nature of Incompatibility: behavioral
    RFE: 6804124

    0 讨论(0)
提交回复
热议问题