Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: Is there a better way to group and sort objects? Date: Tue, 7 Aug 2018 11:33:32 -0400 Organization: A noiseless patient Spider Lines: 58 Message-ID: References: <8c045ff4-98c5-4253-9136-b26b34cf8f77@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Tue, 7 Aug 2018 15:33:34 -0000 (UTC) Injection-Info: reader02.eternal-september.org; posting-host="0c2ed13d1e76a45c68b2c469e9c20a0d"; logging-data="17426"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19Bn2hGhd7P1CV32FVNomTa" User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 Cancel-Lock: sha1:nPq999FvVyxE2zByT7jdegOn/cQ= In-Reply-To: Content-Language: en-US Xref: csiph.com comp.lang.java.programmer:38521 On 8/7/2018 9:44 AM, Eric Sosman wrote: > On 8/7/2018 9:00 AM, Eric Douglas wrote: >> I want to combine and sort objects by key properties and merge their >> secondary properties.  Is there a better way?  This is what I came up >> with.. >> >> public abstract class TestStatic { >>     private static class TestClass extends Object implements >> Comparable { >>         private int var1; >>         private int var2; >> >>         @Override >>         public int compareTo(Object compareMe) { >>             if (compareMe == null || compareMe.getClass() != >> getClass()) { >>                 return 1; >>             } >>             return var1 - ((TestClass) compareMe).getVar1(); >>         } > >     Note that this method violates the Comparable contract.  If you use > this compareTo() method with Arrays.sort() or Collections.sort() or a > SortedMap or whatever, and the objects being compared are a mixture of > different TestClass subclasses, there's no telling what might happen. Now that I think of it, the method violates Comparable in at least two other ways, too. Violation #1: TestClass test = new TestClass(); Integer that = 42; int one = test.compareTo(that); int two = that.compareTo(test); Comparable requires that `one' and `two' have opposite signs or are both zero, but the final line won't even compile, much less yield an acceptable result. (Because of the antisymmetry requirement, I think it is impossible for *any* class to implement Comparable.) Violation #2: TestClass small = new TestClass(); TestClass medium = new TestClass(); TestClass large = new TestClass(); small.setVar1(Integer.MIN_VALUE); large.setVar1(Integer.MAX_VALUE); int smallMedium = small.compareTo(medium); // small < medium int mediumLarge = medium.compareTo(large); // medium < large int smallLarge = small.compareTo(large); // small > large !!! Comparable must define a /total order/, which must be transitive: If X is less than Y and Y is less than Z, X must be less than Z. -- esosman@comcast-dot-net.invalid Eight hundred ninety-seven days to go.