Java 1.5 Tiger A Developers Notebook [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Java 1.5 Tiger A Developers Notebook [Electronic resources] - نسخه متنی

David Flanagan, Brett McLaughlin

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








3.6 Sets of Enums


Another common usage of constants
is to represent a feature set of a particular
item, such as a car, or even something really exciting, like a guitar.
You could then use bitwise operators to compare or check for specific
features. As in the lab on Maps of Enums, the Java language folks realized
this, and added another collection class for the purpose, java.util.EnumSet.


3.6.1 How do I do that?


First, examine the way this scenario might be handled in pre-Tiger days.
Example 3-5 is a simple class that defines some common guitar features.


Example 3-5. Guitar feature set


package com.oreilly.tiger.ch03;
public class OldGuitarFeatures {
public static final int ROSEWOOD = 0x01; // back/sides
public static final int MAHOGANY = 0x02; // back/sides
public static final int ZIRICOTE = 0x04; // back/sides
public static final int SPRUCE = 0x10; // top
public static final int CEDAR = 0x12; // top
public static final int AB_ROSETTE = 0x30; // abalone rosette
public static final int AB_TOP_BORDER = 0x32; // abalone top border
public static final int IL_DIAMONDS = 0x40; // diamond/square inlay
public static final int IL_DOTS = 0x42; // dots inlays
}

These are all features, and are all represented by powers of two. That
allows them to be combined like this:


int bourgeoisD150 = OldGuitarFeatures.ROSEWOOD |
OldGuitarFeatures.SPRUCE |
OldGuitarFeatures.AB_ROSETTE |
OldGuitarFeatures.IL_DIAMONDS;

With this initial work done (you could represent every guitar in a line this
way), you can test a specific guitar for a specific features, using the bitwise
AND operator:


boolean hasAbRosette = (bourgeoisD150 & OldGuitarFeatures.IL_DIAMONDS) != 0;

Looking at the constants in OldGuitarFeatures, you should see that they
are just another case of an enumerated type, and could be represented in
Tiger as shown in Example 3-6.


Example 3-6. Representing guitar features in Tiger


package com.oreilly.tiger.ch03;
public enum GuitarFeatures {
ROSEWOOD, // back/sides
MAHOGANY, // back/sides
ZIRICOTE, // back/sides
SPRUCE, // top
CEDAR, // top
AB_ROSETTE, // abalone rosette
AB_TOP_BORDER, // abalone top border
IL_DIAMONDS, // diamond/square inlay
IL_DOTS // dots inlays
}

NOTE

Be sure and
continue to
compile with the
"-source 1.5" switch.
Using the
provided Ant
scripts takes care
of this, by the
way.

However, operating on these constants with bitwise operators isn't possible,
at least without the help of a new class, java.util.EnumSet. Here
are the methods of this class you should be concerned with, most of
which are factories:


// Returns a new EnumSet with all elements from the supplied type
public static EnumSet allOf(Class elementType);
// Returns a new EnumSet of the same type as the supplied set, but
// with all the values not in the supplied set; a mirror image
public static EnumSet complementOf(EnumSet e);
// Returns a new EnumSet from the provided collection
public static EnumSet copyOf(Collection c);
// Returns a new EnumSet with no values in it
public static EnumSet noneOf(Class elementType);
// Various methods to create an EnumSet with the supplied elements in it
public static EnumSet of(E e[, E e2, E e3, E e4, E e5]);
//Varags version
public static EnumSet of(E... e);
// Creates an EnumSet with a range of values
public static EnumSet range(E from, E to);
// returns a copy of the current set - not a factory method
public EnumSet clone( );

You may have to look at this for a minute to get the sense of thingsthe
format is rather odd. But, to create a new EnumSet of all guitar features,
just use the following:


EnumSet allFeatures = EnumSet.allOf(GuitarFeatures);

Simple enough, right? If you want only the back and side woods, you
could use this notation:


EnumSet backSides = EnumSet.of(GuitarFeatures.ROSEWOOD,
GuitarFeatures.MAHOGANY,
GuitarFeatures.ZIRICOTE);

You could also use the range( ) operator:


EnumSet backSides = EnumSet.range(GuitarFeatures.ROSEWOOD,
GuitarFeatures.ZIRICOTE);


This is really a bad ideareordering of the enum screws this up,
and you can never really completely insulate yourself from that possibility.
Always use of( ) instead of range( ), if at all possible.

complentOf( ) is also a handy method:


EnumSet noAbalone = EnumSet.complementOf(
EnumSet.of(GuitarFeatures.AB_ROSETTE, GuitarFeatures.AB_TOP_BORDER));

With your setup done, you can just use the contains( ) method, available
to all collection classes, to check for a value or values:


EnumSet bourgeoisD150 = EnumSet.of(GuitarFeatures.ROSEWOOD,
GuitarFeatures.SPRUCE,
GuitarFeatures.AB_ROSETTE,
GuitarFeatures.IL_DIAMONDS);
boolean hasAbRosette = bourgeoisD150.contains(GuitarFeatures.AB_ROSETTE);

NOTE

You can't use
varargs to work
with the of( )
method, due to
the usage of
generic types in
the factory
method.
Variable
arguments are
detailed in
Chapter 5.


/ 131