Java IV

Enumerations

  • An enumeration is a group of related constants
  • It can be thought of a type where all the potential values are explicitly enumerated
  • In Java, an Enumeration is created by using the enum keyword
  • This defines a class, so while enumerations can be simple like the following:

    public enum Month{
         JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
      }
    
  • They can also have their own instance variables and methods.

    public enum Month{
          JANUARY (31),
          FEBRUARY (27),
          MARCH (31),
          APRIL (30),
          MAY (31),
          JUNE(30),
          JULY(31),
          AUGUST(31),
          SEPTEMBER(30),
          OCTOBER(31),
          NOVEMBER(30),
          DECEMBER(31);
    
          private final int numDays;
    
          Month(int numDays){
              this.numDays = numDays)
          }
    
          public int numberOfDays(){ return this.numDays;}
    
      }
    

Containers

  • In Java any class that is meant to hold many objects is known as a container class.
    • All the predefined classes of this type implement the Collection interface
  • Some of the most popular are:
    • ArrayList
    • LinkedList
    • HashSet
    • HashMap
  • Originally, all container classes held any type of object, for maximum flexibility

The Problem with using Object

  • Everything Inherits from Object
    • Even if you wanted to enforce type checking, you can't
  • Object objects are really basic and not much can be done with them
    • Unless you cast everyrthing you return from the container

From the textbook:

ArrayList myArray = new ArrayList();
myArray.add(0 new Integer(47));
Integer myInt = (Integer)myArray.get(0);

Generics

  • When faced with problems like this, it would be nice if we could further parameterize the class in some way
    • In Java the solution is generics
    • In C++ the solution is templates
  • All the collection classes are generics as of Java 5
    ArrayList<String> names = new ArrayList<String>();
    

Generic User-Defined Classes

  • Any class can be defined to use generics
  • The type in the angle brackets becomes another parameter

    • Any name can be used, but T is traditional

      public class MyClass<T> {
        private T someVariable
      
        public T getVariable()
        {
            return someVariable.clone();
        }
      }
      

Wildcards

  • When using a generic class as a parameter to a method, the type parameter might not be known
    • The ? wildcard can be used in its place.
      public boolean allTheSame( ArrayList<?> list){
        ...
      }
      
  • Using ? allows an ArrayList of any object to be used as a parameter
    • If more restrictions are needed, ? extends CLASS can be used
      public boolean allTheSame2(ArrayList<? extends Number> list){
        ...
      }
      

Restrictions with Generics

  • There are a few things that can't be done with the type parameter
  • A new object to type T can't be created
    • T object = new T() is invalid
    • There is never any real need for this
  • An array of type T cannot be created
    • T[] arr = new T[100] is invalid
    • An existing container class like ArrayList can be used in its place

Exceptions

  • Java uses exceptions to indicate and handle errors
  • An exception is a class that extends the class Exception (or another class derived from it)
    • Should always have two constructors , an empty one and one that takes a String
    • The gestMessage function should be overridden to provide a programmer relevant information
  • To throw an exception use the keyword throw
    • Because an exception is an object, when throw is used, a new object must be created
    • throw new Exception();

Exception Examples

public void aMethod() throws Exception
{
    ...
    //Something went wrong!
    throw new Exception();
    ...
}
public static void main(String [] args){
    ...
    try{
        aMethod();
    }
    catch(Exception e)
    {
        System.err.println(e.getMessage());
    }

    ...
}

Reflection

  • Methods in Java are not first class objects, they cannot be stored in variables
  • To get around some of the limitations of this, we can use the reflections library in Java
  • This is a large library that can be used to do many things, I will be highlighting how to call a method
  • The first step is to get an object of type Class for the class we are interested in
    Class string = String.class
    

Reflection

  • After having an object representation of the class, we can get an object representing the method
  • We use the method name and parameters for the method to get it (the method signature)
    Method length = string.getMethod("length", null)
    
  • Now that we have an object representation of the method we an run it on an instance of the class
    String s = "This is a string";
      Object stringLength = length.invoke(s,null);
    

Closures

  • Starting in Java 8, there is better support for closures and anonymous functions
  • It is still done in an Object Oriented manner
  • For this class you don't need to know how to write a Java closure, just that they exist

Closures Example

import java.util.function.Consumer;

public class LambdaScopeTest {

    public int x = 0;

    class FirstLevel {

        public int x = 1;

        void methodInFirstLevel(int x) {

            // The following statement causes the compiler to generate
            // the error "local variables referenced from a lambda expression
            // must be final or effectively final" in statement A:
            //
            // x = 99;

            Consumer<Integer> myConsumer = (y) -> 
            {
                System.out.println("x = " + x); // Statement A
                System.out.println("y = " + y);
                System.out.println("this.x = " + this.x);
                System.out.println("LambdaScopeTest.this.x = " +
                    LambdaScopeTest.this.x);
            };

            myConsumer.accept(x);

        }
    }

    public static void main(String... args) {
        LambdaScopeTest st = new LambdaScopeTest();
        LambdaScopeTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);
    }
}

Names, Binding, and Scope

  • Names
    • Case sensitivity?
    • Can reserved words be used?
    • What characters are allowed?
  • Binding
    • When does type binding occur?
  • Scope
    • What is the default scope of a variable?

Data Types

  • What are the data types?
  • Can the user define their own data types?
  • Arrays
    • Are subscripts checked?
    • Can we use slicing?
    • How well supported are multidimensional arrays?
  • Are pointers accessible?
  • Is there type checking?

Expressions and Assignments

  • Does Java have operator precedence?
  • Does Java allow operator overloading?
  • How are type conversions done?
  • Does Java have compound assignment operators (ie +=) ?

Control Structures

  • What is the syntax of an if statement?
  • Does Java have a multiple-select structure (ie switch)?
  • What are Java's counter controlled loops
  • What are Java's logic controlled loops?

Subprograms

  • What is the function syntax in Java
  • Does Java allow functions to be passed as parameters of other functions?
  • Are functions in Java type-checked
  • Can functions in Java return more than one value?
  • Can function definitions be nested?
  • Does Java allow closures?

Example Program

  • A common task in natural language processing is to be able to read a file and calculate various statistics on the words in that file
  • As an in-class exercise, we will write together a program that does the following
    • Reads in a text file and breaks it into words, based on spacing.
    • Counts the frequency of each word
    • Prints a the most common words in the file