Changeset 924534e for doc


Ignore:
Timestamp:
Feb 28, 2024, 11:59:34 AM (7 weeks ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
1d5e5601
Parents:
dc3fbe5
Message:

more proofreading on the enumeration related-work section

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/jiada_liang_MMath/relatedwork.tex

    rdc3fbe5 r924534e  
    77
    88\section{Pascal}
    9 
    10 \lstnewenvironment{pascal}[1][]{% necessary
    11 \lstset{
    12 language=pascal,
    13 escapechar=\$,                                                  % LaTeX escape in code
    14 moredelim=**[is][\color{red}]{@}{@},    % red highlighting @...@
    15 }% lstset
    16 \lstset{#1}% necessary
    17 }{}
     9\lstnewenvironment{pascal}[1][]{\lstset{language=pascal,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    1810
    1911Classic Pascal has the \lstinline[language=pascal]{const} declaration binding a name to a constant literal/expression.
     
    4234
    4335\section{Ada}
    44 
    45 \lstnewenvironment{ada}[1][]{% necessary
    46 \lstset{
    47 language=[2005]Ada,
    48 escapechar=\$,                                                  % LaTeX escape in code
    49 moredelim=**[is][\color{red}]{@}{@},    % red highlighting @...@
    50 literate={'}{\ttfamily'\!}1                             % remove '-' literate as comment
    51 }% lstset
    52 \lstset{#1}% necessary
    53 }{}
     36\lstnewenvironment{ada}[1][]{\lstset{language=[2005]Ada,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},literate={'}{\ttfamily'\!}1}\lstset{#1}}{}
    5437
    5538An Ada enumeration type is an ordered list of constants, called \Newterm{literals} (enumerators).
     
    233216\section{\CC}
    234217\label{s:C++RelatedWork}
    235 
    236 \lstnewenvironment{c++}[1][]{% necessary
    237 \lstset{
    238 language=[GNU]C++,
    239 escapechar=\$,                                                  % LaTeX escape in code
    240 moredelim=**[is][\color{red}]{@}{@},    % red highlighting @...@
    241 }% lstset
    242 \lstset{#1}% necessary
    243 }{}
     218\lstnewenvironment{c++}[1][]{\lstset{language=[GNU]C++,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    244219
    245220\CC is largely backwards compatible with C, so it inherited C's enumerations.
     
    303278enum class srgb @: signed char@ { Red = -1, Green = 0, Blue = 1 };
    304279\end{c++}
    305 There is no implicit conversion from the \lstinline[language=c++]{enum class} type and to its type.
     280There is no implicit conversion from the \lstinline[language=c++]{enum class} type and to its declared type.
    306281\begin{c++}
    307282rgb crgb = rgb::Red;
     
    312287
    313288\section{C\raisebox{-0.7ex}{\LARGE$^\sharp$}\xspace} % latex bug: cannot use \relsize{2} so use \LARGE
    314 
    315 \lstnewenvironment{csharp}[1][]{% necessary
    316 \lstset{
    317 language=[Sharp]C,
    318 escapechar=\$,                                                  % LaTeX escape in code
    319 moredelim=**[is][\color{red}]{@}{@},    % red highlighting @...@
    320 }% lstset
    321 \lstset{#1}% necessary
    322 }{}
     289\label{s:Csharp}
     290\lstnewenvironment{csharp}[1][]{\lstset{language=[Sharp]C,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    323291
    324292% https://www.tutorialsteacher.com/codeeditor?cid=cs-mk8Ojx
     
    326294\Csharp is a dynamically-typed programming-language with a scoped, integral enumeration-type similar to C/\CC enumeration.
    327295\begin{csharp}
    328 enum Weekday : byte { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday@,@ };
     296enum Weekday : byte { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun@,@ };
    329297\end{csharp}
    330298The default underlying type is @int@, with auto-incrementing, implicit/explicit initialization, terminator comma, and optional integral typing (default @int@)
     
    332300As well, there is an explicit bidirectional conversion between an enumeration and its integral type, and an implicit conversion to the enumerator label in display contexts.
    333301\begin{csharp}
    334 int day = (int)Weekday.Friday;                  $\C{// day == 10}$
    335 Weekday weekday = (Weekdays)42;                 $\C{// weekday == 42}$
    336 Console.WriteLine( Weekday.Friday );    $\C{// print Friday}$
    337 string mon = Weekday.Monday.ToString();
     302int day = (int)Weekday.Fri;             $\C{// day == 10}$
     303Weekday weekday = (Weekdays)42;         $\C{// weekday == 42, logically invalid}$
     304Console.WriteLine( Weekday.Fri ); $\C{// print Fri}$
     305string mon = Weekday.Mon.ToString(); $\C{// mon == "Mon"}$
    338306\end{csharp}
    339307
     
    348316\begin{csharp}
    349317@[Flags]@ public enum Weekday {
    350         None = 0x0, Monday = 0x1, Tuesday = 0x2, Wednesday = 0x4,
    351         Thursday = 0x8, Friday = 0x10, Saturday = 0x20, Sunday = 0x40,
    352         Weekend = @Saturday | Sunday@,
    353         Weekdays = @Monday | Tuesday | Wednesday | Thursday | Friday@
    354 }
    355 Weekday meetings = @Weekday.Monday | Weekday.Wednesday@; // 0x5
     318        None = 0x0, Mon = 0x1, Tue = 0x2, Wed = 0x4,
     319        Thu = 0x8, Fri = 0x10, Sat = 0x20, Sun = 0x40,
     320        Weekend = @Sat | Sun@,
     321        Weekdays = @Mon | Tue | Wed | Thu | Fri@
     322}
     323Weekday meetings = @Weekday.Mon | Weekday.Wed@; // 0x5
    356324\end{csharp}
    357325
    358 \Csharp supports an enumeration class to embed enumeration operations, where the enumerators are objects.
     326\VRef[Figure]{CsharpFreeVersusClass} shows an enumeration with free routines for manipulation, and embedding the enumeration and operations into an enumeration class.
     327The key observation is that an enumeration class is just a structuring mechanism without any additional semantics.
     328
     329% https://learn.microsoft.com/en-us/dotnet/api/system.enum?view=net-8.0
     330
     331\begin{figure}
     332\centering
     333\lstDeleteShortInline@
     334\begin{tabular}{@{}l|l@{}}
     335\multicolumn{1}{@{}c|}{non-object oriented} & \multicolumn{1}{c@{}}{object oriented} \\
     336\hline
    359337\begin{csharp}
    360 public class PaymentType : Enumeration {
    361     public static readonly PaymentType DebitCard = new PaymentType(0);
    362     public static readonly PaymentType CreditCard = new PaymentType(1);
    363     private PaymentType(int value, [CallerMemberName] string name = null) : base(value, name) { }
     338public class Program {
     339
     340        enum Weekday {
     341                Mon, Tue, Wed, Thu, Fri, Sat, Sun };
     342
     343
     344        static bool isWeekday( Weekday wd ) {
     345                return Weekday.Mon <= wd
     346                        && wd <= Weekday.Fri;
     347        }
     348        static bool isWeekend( Weekday wd ) {
     349                return Weekday.Sat <= wd
     350                        && wd <= Weekday.Sun;
     351        }
     352
     353
     354        public static void Main() {
     355                Weekday day = Weekday.Sat;
     356
     357                Console.WriteLine( isWeekday( day ) );
     358                Console.WriteLine( isWeekend( day ) );
     359        }
    364360}
    365361\end{csharp}
    366 Find a meaningful example and test it.
     362&
     363\begin{csharp}
     364public class Program {
     365        public @class@ WeekDay {
     366                public enum Weekday {
     367                        Mon=-4, Tue=-3, Wed=-2, Thu=-1,
     368                        Fri=0, Sat=1, Sun=2 };
     369                Weekday day;
     370                public bool isWeekday() {
     371                        return day <= 0;
     372
     373                }
     374                public bool isWeekend() {
     375                        return day > 0
     376
     377                }
     378                public WeekDay( Weekday d ) { day = d; }
     379        }
     380        public static void Main() {
     381                WeekDay cday = new
     382                                WeekDay( WeekDay.Weekday.Sat );
     383                Console.WriteLine( cday.isWeekday() );
     384                Console.WriteLine( cday.isWeekend() );
     385        }
     386}
     387\end{csharp}
     388\end{tabular}
     389\lstMakeShortInline@
     390\caption{\Csharp: Free Routine Versus Class Enumeration}
     391\label{CsharpFreeVersusClass}
     392\end{figure}
    367393
    368394
    369395\section{Golang}
    370 
    371 \lstnewenvironment{Go}[1][]{% necessary
    372 \lstset{
    373 language=Go,
    374 escapechar=\$,                                                  % LaTeX escape in code
    375 moredelim=**[is][\color{red}]{@}{@},    % red highlighting @...@
    376 }% lstset
    377 \lstset{#1}% necessary
    378 }{}
    379 
    380 The Golang enumeration is similar to classic Pascal \lstinline[language=pascal]{const}, binding a name to a constant literal/expression.
     396\lstnewenvironment{Go}[1][]{\lstset{language=Go,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
     397
     398Golang provides a mechanism similar to classic Pascal \lstinline[language=pascal]{const}, binding a name to a constant literal/expression (pseudo enumeration).
    381399\begin{Go}
    382400const ( R = 0; G; B )                                   $\C{// implicit: 0 0 0}$
     
    401419Auto-incrementing stops after an explicit initialization.
    402420\begin{Go}
    403 const ( Monday = iota; Tuesday; Wednesday; // 0, 1, 2
    404          @Thursday = 10@; Friday; Saturday; Sunday ) // 10, 10, 10, 10
     421const ( Mon = iota; Tue; Wed; // 0, 1, 2
     422         @Thu = 10@; Fri; Sat; Sun ) // 10, 10, 10, 10
    405423\end{Go}
    406424Auto-incrementing can be restarted with an expression containing \emph{one} \lstinline[language=Go]{iota}.
    407425\begin{Go}
    408426const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@; V5 ) // 0 1 7 3 4
    409 const ( Monday = iota; Tuesday; Wednesday; // 0, 1, 2
    410          @Thursday = 10;@ Friday = @iota - Wednesday + Thursday - 1@; Saturday; Sunday ) // 10, 11, 12, 13
     427const ( Mon = iota; Tue; Wed; // 0, 1, 2
     428         @Thu = 10;@ Fri = @iota - Wed + Thu - 1@; Sat; Sun ) // 10, 11, 12, 13
    411429\end{Go}
    412430Note, \lstinline[language=Go]{iota} is advanced for an explicitly initialized enumerator, like the underscore @_@ identifier.
    413431
     432Basic switch and looping are possible.
     433\begin{cquote}
     434\lstDeleteShortInline@
     435\setlength{\tabcolsep}{15pt}
     436\begin{tabular}{@{}ll@{}}
     437\begin{Go}
     438day := Mon;
     439switch day {
     440  case Mon, Tue, Wed, Thu, Fri:
     441        fmt.Println( "weekday" );
     442  case Sat, Sun:
     443        fmt.Println( "weekend" );
     444}
     445\end{Go}
     446&
     447\begin{Go}
     448
     449for i := Mon; i <= Sun; i += 1 {
     450    fmt.Println( i )
     451}
     452
     453
     454
     455\end{Go}
     456\end{tabular}
     457\lstMakeShortInline@
     458\end{cquote}
     459The loop prints the values from 0 to 13 because there is no actual enumeration.
     460
    414461
    415462\section{Java}
    416 
    417 \lstnewenvironment{Java}[1][]{% necessary
    418 \lstset{
    419 language=Java,
    420 escapechar=\$,                                                  % LaTeX escape in code
    421 moredelim=**[is][\color{red}]{`}{`},    % red highlighting @...@
    422 }% lstset
    423 \lstset{#1}% necessary
    424 }{}
    425 
    426 Here's a quick and simple example of an enum that defines the status of a pizza order; the order status can be ORDERED, READY or DELIVERED:
     463\lstnewenvironment{Java}[1][]{\lstset{language=Java,escapechar=\$,moredelim=**[is][\color{red}]{!}{!},}\lstset{#1}}{}
     464
     465Every enumeration in Java is an enumeration class.
     466For a basic enumeration
    427467\begin{Java}
    428 public enum PizzaStatus {
    429     ORDERED,
    430     READY,
    431     DELIVERED;
    432 }
     468enum Weekday { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
     469Weekday day = Weekday.Sat;
    433470\end{Java}
    434 Additionally, enums come with many useful methods that we would otherwise need to write if we were using traditional public static final constants.
    435 
    436 \paragraph{Custom Enum Methods}
    437 
    438 Now that we have a basic understanding of what enums are and how we can use them, we'll take our previous example to the next level by defining some extra API methods on the enum:
     471the scoped enumerators are an ordered list of @final@ methods of type integer, ordered left to right starting at 0, increasing by 1.
     472The value of an enumeration instance is restricted to the enumeration's enumerators.
     473There is an implicit integer variable in the enumeration used to store the value of an enumeration instance.
     474The position (ordinal) and label are accessible, and the value is the same as the position.
    439475\begin{Java}
    440 public class Pizza {
    441     private PizzaStatus status;
    442     public enum PizzaStatus {
    443         ORDERED,
    444         READY,
    445         DELIVERED;
    446     }
    447     public boolean isDeliverable() {
    448         if (getStatus() == PizzaStatus.READY) {
    449             return true;
    450         }
    451         return false;
    452     }
    453     // Methods that set and get the status variable.
    454 }
     476System.out.println( !day.ordinal()! + " " + !day! ); // 5 Sat
    455477\end{Java}
    456 
    457 \paragraph{Comparing Enum Types Using "==" Operator}
    458 
    459 Since enum types ensure that only one instance of the constants exist in the JVM, we can safely use the "==" operator to compare two variables, like we did in the above example.
    460 Furthermore, the "==" operator provides compile-time and run-time safety.
    461 
    462 First, we'll look at run-time safety in the following snippet, where we'll use the "==" operator to compare statuses.
    463 Either value can be null and we won't get a NullPointerException. Conversely, if we use the equals method, we will get a NullPointerException:
     478There are no implicit conversions to/from an enumerator and its underlying type.
     479
     480To explicitly assign enumerator values, the enumeration must specify an explicit type in the enumeration class.
    464481\begin{Java}
    465 if(testPz.getStatus().equals(Pizza.PizzaStatus.DELIVERED));
    466 if(testPz.getStatus() == Pizza.PizzaStatus.DELIVERED);
     482enum Weekday {
     483        Mon( -4 ), Tue( -3 ), Wed( -2 ), Thu( -1 ), Fri( 0 ), Sat( 1 ), Sun( 2 ); // must appear first
     484        private int day;                                        $\C{// underlying enumeration type}$
     485        private Weekday( int d ) { day = d; } $\C{// used to initialize enumerators and instances}$
     486};
     487Weekday day = Weekday.Sat;                              $\C{// implicit constructor call}$
    467488\end{Java}
    468 As for compile-time safety, let's look at an example where we'll determine that an enum of a different type is equal by comparing it using the equals method.
    469 This is because the values of the enum and the getStatus method coincidentally are the same;
    470 however, logically the comparison should be false. We avoid this issue by using the "==" operator.
    471 
    472 The compiler will flag the comparison as an incompatibility error:
     489The position, value, and label are accessible.
    473490\begin{Java}
    474 if(testPz.getStatus().equals(TestColor.GREEN));
    475 if(testPz.getStatus() == TestColor.GREEN);
     491System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day! );  // 5 1 Sat
    476492\end{Java}
    477 
    478 \paragraph{Using Enum Types in Switch Statements}
    479 
    480 We can use enum types in switch statements also:
     493The constructor is private so only initialization or assignment can be used to set an enumeration, which ensures only corresponding enumerator values are allowed.
     494
     495Like \Csharp, \VRef[Figure]{f:JavaFreeVersusClass} shows the same example for an enumeration with free routines for manipulation, and embedding the enumeration and operations into an enumeration class.
     496
     497\begin{figure}
     498\centering
     499\lstDeleteShortInline@
     500\begin{tabular}{@{}l|l@{}}
     501\multicolumn{1}{@{}c|}{non-object oriented} & \multicolumn{1}{c@{}}{object oriented} \\
     502\hline
    481503\begin{Java}
    482 public int getDeliveryTimeInDays() {
    483     switch (status) {
    484         case ORDERED: return 5;
    485         case READY: return 2;
    486         case DELIVERED: return 0;
    487     }
    488     return 0;
     504public class test {
     505
     506        enum Weekday {
     507                Mon, Tue, Wed, Thu, Fri, Sat, Sun };
     508
     509        static boolean isWeekday( Weekday wd ) {
     510                return Weekday.Mon.ordinal() <= wd.ordinal()
     511                        && wd.ordinal() <= Weekday.Fri.ordinal();
     512        }
     513        static boolean isWeekend( Weekday wd ) {
     514                return Weekday.Sat.ordinal() <= wd.ordinal()
     515                        && wd.ordinal() <= Weekday.Sun.ordinal();
     516        }
     517
     518
     519        public static void main( String[] args ) {
     520                Weekday day = Weekday.Sat;
     521                System.out.println( isWeekday( day ) );
     522                System.out.println( isWeekend( day ) );
     523        }
    489524}
    490525\end{Java}
    491 
    492 \paragraph{Fields, Methods and Constructors in Enums}
    493 
    494 We can define constructors, methods, and fields inside enum types, which makes them very powerful.
    495 
    496 Next, let's extend the example above by implementing the transition from one stage of a pizza order to another.
    497 We'll see how we can get rid of the if and switch statements used before:
     526&
    498527\begin{Java}
    499 public class Pizza {
    500     private PizzaStatus status;
    501     public enum PizzaStatus {
    502         ORDERED (5){
    503             @Override
    504             public boolean isOrdered() {
    505                 return true;
    506             }
    507         },
    508         READY (2){
    509             @Override
    510             public boolean isReady() {
    511                 return true;
    512             }
    513         },
    514         DELIVERED (0){
    515             @Override
    516             public boolean isDelivered() {
    517                 return true;
    518             }
    519         };
    520 
    521         private int timeToDelivery;
    522         public boolean isOrdered() {return false;}
    523         public boolean isReady() {return false;}
    524         public boolean isDelivered(){return false;}
    525         public int getTimeToDelivery() {
    526             return timeToDelivery;
    527         }
    528         PizzaStatus (int timeToDelivery) {
    529             this.timeToDelivery = timeToDelivery;
    530         }
    531     }
    532     public boolean isDeliverable() {
    533         return this.status.isReady();
    534     }
    535     public void printTimeToDeliver() {
    536         System.out.println("Time to delivery is " +
    537           this.getStatus().getTimeToDelivery());
    538     }
    539     // Methods that set and get the status variable.
     528public class test {
     529        public !enum! WeekDay {
     530                Mon(-4), Tue(-3), Wed(-2), Thu(-1),
     531                        Fri(0), Sat(1), Sun(2);
     532                private int day;
     533                public boolean isWeekday() {
     534                        return day <= 0;
     535
     536                }
     537                public boolean isWeekend() {
     538                        return day > 0;
     539
     540                }
     541                private WeekDay( int d ) { day = d; }
     542        }
     543        public static void main( String[] args ) {
     544                WeekDay day = WeekDay.Sat;
     545                System.out.println( day.isWeekday() );
     546                System.out.println( day.isWeekend() );
     547        }
    540548}
    541549\end{Java}
    542 The test snippet below demonstrates how this works:
     550\end{tabular}
     551\lstMakeShortInline@
     552\caption{Java: Free Routine Versus Class Enumeration}
     553\label{f:JavaFreeVersusClass}
     554\end{figure}
     555
     556An enumeration can appear in a @switch@ statement, but no ranges.
    543557\begin{Java}
    544 @Test
    545 public void givenPizaOrder_whenReady_thenDeliverable() {
    546     Pizza testPz = new Pizza();
    547     testPz.setStatus(Pizza.PizzaStatus.READY);
    548     assertTrue(testPz.isDeliverable());
     558switch ( day ) {
     559  case Mon: case Tue: case Wed: case Thu: case Fri:
     560        System.out.println( "weekday" );
     561        break;
     562  case Sat: case Sun:
     563        System.out.println( "weekend" );
     564        break;
    549565}
    550566\end{Java}
    551 
    552 \paragraph{EnumSet and EnumMap}
    553 
    554 \paragraph{EnumSet}
    555 
    556 The EnumSet is a specialized Set implementation that's meant to be used with Enum types.
    557 
    558 Compared to a HashSet, it's a very efficient and compact representation of a particular Set of Enum constants, owing to the internal Bit Vector Representation that's used.
    559 It also provides a type-safe alternative to traditional int-based "bit flags," allowing us to write concise code that's more readable and maintainable.
    560 
    561 The EnumSet is an abstract class that has two implementations, RegularEnumSet and JumboEnumSet, one of which is chosen depending on the number of constants in the enum at the time of instantiation.
    562 
    563 Therefore, it's a good idea to use this set whenever we want to work with a collection of enum constants in most scenarios (like subsetting, adding, removing, and bulk operations like containsAll and removeAll), and use Enum.values() if we just want to iterate over all possible constants.
    564 
    565 In the code snippet below, we can see how to use EnumSet to create a subset of constants:
     567Looping over an enumeration is done using method @values@, which returns the array of enumerator values.
    566568\begin{Java}
    567 public class Pizza {
    568     private static EnumSet<PizzaStatus> undeliveredPizzaStatuses =
    569       EnumSet.of(PizzaStatus.ORDERED, PizzaStatus.READY);
    570     private PizzaStatus status;
    571     public enum PizzaStatus {
    572         ...
    573     }
    574     public boolean isDeliverable() {
    575         return this.status.isReady();
    576     }
    577     public void printTimeToDeliver() {
    578         System.out.println("Time to delivery is " +
    579           this.getStatus().getTimeToDelivery() + " days");
    580     }
    581     public static List<Pizza> getAllUndeliveredPizzas(List<Pizza> input) {
    582         return input.stream().filter(
    583           (s) -> undeliveredPizzaStatuses.contains(s.getStatus()))
    584             .collect(Collectors.toList());
    585     }
    586     public void deliver() {
    587         if (isDeliverable()) {
    588             PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy()
    589               .deliver(this);
    590             this.setStatus(PizzaStatus.DELIVERED);
    591         }
    592     }
    593     // Methods that set and get the status variable.
     569for ( Weekday iday : Weekday.values() ) {
     570        System.out.println( iday.ordinal() + " " + iday + " " );
    594571}
    595572\end{Java}
    596573
    597 Executing the following test demonstrates the power of the EnumSet implementation of the Set interface:
    598 \begin{Java}
    599 @Test
    600 public void givenPizaOrders_whenRetrievingUnDeliveredPzs_thenCorrectlyRetrieved() {
    601     List<Pizza> pzList = new ArrayList<>();
    602     Pizza pz1 = new Pizza();
    603     pz1.setStatus(Pizza.PizzaStatus.DELIVERED);
    604 
    605     Pizza pz2 = new Pizza();
    606     pz2.setStatus(Pizza.PizzaStatus.ORDERED);
    607 
    608     Pizza pz3 = new Pizza();
    609     pz3.setStatus(Pizza.PizzaStatus.ORDERED);
    610 
    611     Pizza pz4 = new Pizza();
    612     pz4.setStatus(Pizza.PizzaStatus.READY);
    613 
    614     pzList.add(pz1);
    615     pzList.add(pz2);
    616     pzList.add(pz3);
    617     pzList.add(pz4);
    618 
    619     List<Pizza> undeliveredPzs = Pizza.getAllUndeliveredPizzas(pzList);
    620     assertTrue(undeliveredPzs.size() == 3);
    621 }
    622 \end{Java}
    623 
    624 \paragraph{EnumMap}
    625 
    626 EnumMap is a specialized Map implementation meant to be used with enum constants as keys.
    627 Compared to its counterpart HashMap, it's an efficient and compact implementation that's internally represented as an array:
    628 \begin{Java}
    629 EnumMap<Pizza.PizzaStatus, Pizza> map;
    630 \end{Java}
    631 Let's look at an example of how we can use it in practice:
    632 \begin{Java}
    633 public static EnumMap<PizzaStatus, List<Pizza>>
    634   groupPizzaByStatus(List<Pizza> pizzaList) {
    635     EnumMap<PizzaStatus, List<Pizza>> pzByStatus =
    636       new EnumMap<PizzaStatus, List<Pizza>>(PizzaStatus.class);
    637    
    638     for (Pizza pz : pizzaList) {
    639         PizzaStatus status = pz.getStatus();
    640         if (pzByStatus.containsKey(status)) {
    641             pzByStatus.get(status).add(pz);
    642         } else {
    643             List<Pizza> newPzList = new ArrayList<Pizza>();
    644             newPzList.add(pz);
    645             pzByStatus.put(status, newPzList);
    646         }
    647     }
    648     return pzByStatus;
    649 }
    650 \end{Java}
    651 Executing the following test demonstrates the power of the EnumMap implementation of the Map interface:
    652 \begin{Java}
    653 @Test
    654 public void givenPizaOrders_whenGroupByStatusCalled_thenCorrectlyGrouped() {
    655     List<Pizza> pzList = new ArrayList<>();
    656     Pizza pz1 = new Pizza();
    657     pz1.setStatus(Pizza.PizzaStatus.DELIVERED);
    658 
    659     Pizza pz2 = new Pizza();
    660     pz2.setStatus(Pizza.PizzaStatus.ORDERED);
    661 
    662     Pizza pz3 = new Pizza();
    663     pz3.setStatus(Pizza.PizzaStatus.ORDERED);
    664 
    665     Pizza pz4 = new Pizza();
    666     pz4.setStatus(Pizza.PizzaStatus.READY);
    667 
    668     pzList.add(pz1);
    669     pzList.add(pz2);
    670     pzList.add(pz3);
    671     pzList.add(pz4);
    672 
    673     EnumMap<Pizza.PizzaStatus,List<Pizza>> map = Pizza.groupPizzaByStatus(pzList);
    674     assertTrue(map.get(Pizza.PizzaStatus.DELIVERED).size() == 1);
    675     assertTrue(map.get(Pizza.PizzaStatus.ORDERED).size() == 2);
    676     assertTrue(map.get(Pizza.PizzaStatus.READY).size() == 1);
    677 }
    678 \end{Java}
    679 
    680 \paragraph{Singleton Pattern}
    681 
    682 Normally, implementing a class using the Singleton pattern is quite non-trivial.
    683 Enums provide a quick and easy way of implementing singletons.
    684 
    685 In addition, since the enum class implements the Serializable interface under the hood, the class is guaranteed to be a singleton by the JVM.
    686 This is unlike the conventional implementation, where we have to ensure that no new instances are created during deserialization.
    687 
    688 In the code snippet below, we see how we can implement a singleton pattern:
    689 \begin{Java}
    690 public enum PizzaDeliverySystemConfiguration {
    691     INSTANCE;
    692     PizzaDeliverySystemConfiguration() {
    693         // Initialization configuration which involves
    694         // overriding defaults like delivery strategy
    695     }
    696 
    697     private PizzaDeliveryStrategy deliveryStrategy = PizzaDeliveryStrategy.NORMAL;
    698 
    699     public static PizzaDeliverySystemConfiguration getInstance() {
    700         return INSTANCE;
    701     }
    702 
    703     public PizzaDeliveryStrategy getDeliveryStrategy() {
    704         return deliveryStrategy;
    705     }
    706 }
    707 \end{Java}
    708 
    709 \paragraph{Strategy Pattern}
    710 
    711 Conventionally, the Strategy pattern is written by having an interface that is implemented by different classes.
    712 
    713 Adding a new strategy means adding a new implementation class.
    714 With enums, we can achieve this with less effort, and adding a new implementation means simply defining another instance with some implementation.
    715 
    716 The code snippet below shows how to implement the Strategy pattern:
    717 \begin{Java}
    718 public enum PizzaDeliveryStrategy {
    719     EXPRESS {
    720         @Override
    721         public void deliver(Pizza pz) {
    722             System.out.println("Pizza will be delivered in express mode");
    723         }
    724     },
    725     NORMAL {
    726         @Override
    727         public void deliver(Pizza pz) {
    728             System.out.println("Pizza will be delivered in normal mode");
    729         }
    730     };
    731 
    732     public abstract void deliver(Pizza pz);
    733 }
    734 \end{Java}
    735 Then we add the following method to the Pizza class:
    736 \begin{Java}
    737 public void deliver() {
    738     if (isDeliverable()) {
    739         PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy()
    740           .deliver(this);
    741         this.setStatus(PizzaStatus.DELIVERED);
    742     }
    743 }
    744 
    745 @Test
    746 public void givenPizaOrder_whenDelivered_thenPizzaGetsDeliveredAndStatusChanges() {
    747     Pizza pz = new Pizza();
    748     pz.setStatus(Pizza.PizzaStatus.READY);
    749     pz.deliver();
    750     assertTrue(pz.getStatus() == Pizza.PizzaStatus.DELIVERED);
    751 }
    752 \end{Java}
    753 
    754 8. Java 8 and Enums
    755 
    756 We can rewrite the Pizza class in Java 8, and see how the methods getAllUndeliveredPizzas() and groupPizzaByStatus() become so concise with the use of lambdas and the Stream APIs:
    757 \begin{Java}
    758 public static List<Pizza> getAllUndeliveredPizzas(List<Pizza> input) {
    759     return input.stream().filter(
    760       (s) -> !deliveredPizzaStatuses.contains(s.getStatus()))
    761         .collect(Collectors.toList());
    762 }
    763 
    764 public static EnumMap<PizzaStatus, List<Pizza>>
    765   groupPizzaByStatus(List<Pizza> pzList) {
    766     EnumMap<PizzaStatus, List<Pizza>> map = pzList.stream().collect(
    767       Collectors.groupingBy(Pizza::getStatus,
    768       () -> new EnumMap<>(PizzaStatus.class), Collectors.toList()));
    769     return map;
    770 }
    771 \end{Java}
     574As well, Java provides an @EnumSet@ where the underlying type is an efficient set of bits, one per enumeration \see{\Csharp \lstinline{Flags}, \VRef{s:Csharp}}, providing (logical) operations on groups of enumerators.
     575There is also a specialized version of @HashMap@ with enumerator keys, which has performance benefits.
     576
     577Enumeration inheritence is disallowed because an enumeration is @final@.
     578
    772579
    773580
     
    778585
    779586\section{Swift}
    780 
    781 \lstnewenvironment{swift}[1][]{% necessary
    782 \lstset{
    783 language=Swift,
    784 escapechar=\$,                                                  % LaTeX escape in code
    785 moredelim=**[is][\color{red}]{@}{@},    % red highlighting @...@
    786 }% lstset
    787 \lstset{#1}% necessary
    788 }{}
     587\lstnewenvironment{swift}[1][]{\lstset{language=Swift,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{}
    789588
    790589Model custom types that define a list of possible values.
Note: See TracChangeset for help on using the changeset viewer.