Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!eternal-september.org!feeder.eternal-september.org!mx04.eternal-september.org!.POSTED!not-for-mail From: Joshua Cranmer Newsgroups: comp.lang.java.programmer Subject: Re: Enumset.contains Date: Sat, 10 Nov 2012 20:38:21 -0600 Organization: A noiseless patient Spider Lines: 69 Message-ID: References: <6btq9811qn454a7s9u4dka81qn6k6e2n56@4ax.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Sun, 11 Nov 2012 02:38:23 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="5a9707252ba5efb9bece56d1f4656a90"; logging-data="6419"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+zW0HhjE8cueXweKi3ALD6+wLQyNMbViY=" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20121026 Thunderbird/16.0.2 In-Reply-To: Cancel-Lock: sha1:wNcaPYN5GkT1CSBHCEQJD8HHzNg= Xref: csiph.com comp.lang.java.programmer:19693 On 11/10/2012 6:56 PM, Roedy Green wrote: > On Sat, 10 Nov 2012 00:30:28 +0100, Robert Klemme > wrote, quoted or indirectly quoted > someone who said : > >>> intersection >> retainAll() > > These are methods of AbstractSet inherited and in my opinion > preposterously pedestrian. You might as well have used a TreeSet as an > Enum. A proper intersection method for EnumSets would be implemented > with a single AND machine instruction. The implementations aren't actually inherited from AbstractSet. If you pay careful attention to the documentation, you'll notice that EnumSet is an abstract class. The actual implementation is one of two classes, RegularEnumSet or JumboEnumSet, which is selected based on the number of elements in the enum. In these subclasses, the methods are indeed overridden for increased performance. From the source code of java.util.RegularEnumSet (the actual implementation of EnumSets for enums with <= 64 characters): public boolean retainAll(Collection c) { if (!(c instanceof RegularEnumSet)) return super.retainAll(c); RegularEnumSet es = (RegularEnumSet)c; if (es.elementType != elementType) { boolean changed = (elements != 0); elements = 0; return changed; } long oldElements = elements; elements &= es.elements; return elements != oldElements; } Up to the necessary boilerplate, it is exactly an AND machine instruction. > Mathematicians have been using the term "intersection" for at least > 100 years. I think it was improper of Sun/Oracle to rename the > functions. Except that java.util.Set isn't a set in the mathematical sense, but a specification of an abstract datatype called a "set" (a collection of items such that no item is contained more than once). There is a distinction between the two; in particular, a mathematical set is an intrinsically immutable object while the set datatype is definitely mutable. Case in point: what would a.intersection(b) do? 1. Return a set c which consists of all elements that are both in a and b at the point of the function call. 2. Return a set c which gives you a view of the elements that are both in a and b at the time of any given function call in c (so if you remove an element from a, it may be removed from c as well). 3. Update a to consist only of the elements that it shares in common with b. You can make arguments for doing any of these three things (and perhaps choose a better name than a noun for a method call). On the other hand, retainAll tells you exactly which of the three it will do. To paraphrase one of my programming books, relationships in object-oriented programming don't necessarily follow the same relationships in mathematics, even if they have the same name. -- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald E. Knuth