Collections & Sorting

Stamp Collector

Collections is a class with only static methods, devoted to operations on objects with collecting characteristics, List, Map, and Set. It can:

  • copy collections
  • put all contents of a collection into another
  • sort collections
  • reverse the order of collections
  • randomly shuffle a collection
  • find frequency of elements
  • and more, but perhaps the most often used is sort.

Sorting our objects can be done by three standard methods:

  • equals()
  • compareTo()
  • compare()

The latter two are the ways that Collections uses to sort data.

 

equals()

This is a method included with class Object, so therefore it is included with every type of object.

It returns a boolean value (true or false) saying whether this object is “equal” with another.

It can and is expected to be overridden to compare objects by your customized way.

Example (try it):

class Cat
{
   int age;
   Cat(int age)
   {
      this.age = age;
   }

   public boolean equals(Cat other)
   {
      return this.age == other.age;
   }
}

 

compareTo()

This method comes from the java.lang.Comparable<T> interface:

int compareTo(T object)

is implemented to compare this object with another to give a negative value for this object being less than, 0 for equals, or positive value for greater than the other.

This is the more convenient compare method, but must be implemented in every class you want to compare.

Example (try it):

class Cat implements Comparable<Cat>
{
   int age;
   Cat(int age)
   {
      this.age = age;
   }
 
   public int compareTo(Cat other)
   {
      if (this.age < other.age)
       return -1;
      else if (this.age == other.age)
       return 0;
      else
       return 1;
   }
}

Note that a simpler way to write the method above is:

return this.age - other.age; //- value for <, 0 for ==, + value for >

 

compare()

This method comes from the java.util.Comparator<T> interface:

int compare(T obj1, T obj2)

is implemented in a separate class that compares another class’s objects to give a negative value for the first object being less than, 0 for equals, or positive value for greater than the second object.

It is needed when you cannot make a class implement compareTo() because it is not modifiable. It is also used when you want different ways to compare objects, not just one (such as by name or age)..

Example (try it):

class Cat
{
   int age;
   Cat(int age)
   {
      this.age = age;
   }
}

class CatComparatorByAge implements Comparator<Cat>
{
   public int compare(Cat first, Cat second)
   {
      if (first.age < second.age)
         return -1;
      else if (first.age == second.age)
         return 0;
      else
         return 1;
   }
}
Please like & share:

Design Patterns

Design patterns are common, effective solutions to software design problems.

 

Iterator Pattern

An object traverses and accesses elements of a collection, rather than the programmer directly manipulating the collection.

Purpose is to simplify traversal of a collection and hide the details of its inner workings.

Example:

LinkedList list = new LinkedList();
//...add elements...
ListIterator iterator = list.listIterator();
while (iterator.hasNext())
{
     Object element = iterator.next();
     //do something with element
}

This is better than a version of LinkedList that would allow the user to access its nodes directly, like so:

Node node = list.head;
while(node != null)
{
     //do something with node.element
     node = node.next;
}

This is because this complicates things (in working with links) and thus is prone to errors.

In Java, list iterators can be imagined like the cursor in a text processor that moves along characters, the characters being like elements of a list.

Adding element adds it and advances the iterator position by one.

Adding element adds it and advances iterator position by one.

 

Singleton Pattern

A public one-of-a-kind object exists as a static variable.

Purpose is to ensure only one object of a type is publicly available.

Example:

class System
{
     //single God instance.
     static God god = new God(); 
     private class God
     {
          void create()
          {
          }
     }
}

 

Observer Pattern

Henri_Matisse,_1916-17,_Le_Peintre_dans_son_atelier_(The_Painter_and_His_Model),_oil_on_canvas,_146.5_x_97_cm,_Musée_National_d'Art_Moderne,_Centre_Georges_Pompidou,_Paris

An object notifies another object (the “observer”) whenever a change to a data has occurred.

Purpose for this pattern is encapsulation of data and distribution of responsibility.

Example:

//make button.
final JButton button = new JButton();
 
//make observer for mouse events.
MouseListener listener = new MouseAdapter()
{
     public void mouseClicked(MouseEvent e)
     {
          button.setText("clicked");
     }
};
 
//make it observe the button.
button.addMouseListener(listener);

Model-View-Controller (MVC) is an architecture that uses this pattern. Example: visualize a posing artist’s model (Model), a painter of the model (View), and a director of the model (Controller). The director controls the model’s state. Whenever it does, the model notifies the painter to update his representation of the model visible to the user.

Example:

// Model.
class Model
 {
     String state;
     Painter painter; //representer of model
 
     //notify painter when state changed.
     void notify()
     {
          painter.repaint(this);
     }
}
 
// View.
class Painter
{
     void repaint(Model model)
     {
          //update representation of model.
     }
}
 
// Controller.
class Director
{
     Model model;
     Director(Model model)
     {
          this.model = model;
     }

     void setModelState(String newState)
     {
          model.state = newState;
          model.notify();
     }
}

//The tester.
class Tester
{
     public static void main(String[] args)
     {
           Model model = new Model();
           model.painter = new Painter();
           Director director = new Director(model);
           director.setModelState("Sitting");
     }
}

Another way to think of Model-View-Controller, is Data-Output-Input. the input changes the data (as an interface to it), while the output represents the data to the user in whatever state it currently is in.

 

Adapter Pattern

A class (the “adapter”) implements an interface by blank methods to save its users from implementing every method when some are unneeded.

Purpose is nothing more than saving code.

Example:

//make button.
final JButton button = new JButton();
 
//make adapter implementing one method of an interface.
MouseListener listener = new MouseAdapter()
{
     public void mouseClicked(ActionEvent event)
     {
          button.setText("Clicked");
     }
};
button.addMouseListener(listener);

This is the same as, but shorter than, this:

//make button.
final JButton button = new JButton();

//make adapter implementing one method of an interface.
MouseListener listener = new MouseListener()
{
     public void mouseClicked(MouseEvent e)
     {
            button.setText("Clicked");
     }
     
 
     //implement unneeded methods as blank.
     public void mouseMoved(ActionEvent e)
     {  
     }
     public void mouseEntered(MouseEvent e)
     {
     }
 
     public void mouseExited(MouseEvent e)
     {
     }
 
     public void mousePressed(MouseEvent e)
     {
     }
 
     public void mouseReleased(MouseEvent e)
     {
     }
};
button.addMouseListener(listener);

 

Composite Pattern

composite

A class acts a container for its siblings and using this container simply uses all its contained objects, as a proxy.

Example:

abstract class Item
{
     abstract void use();
}
class Toy extends Item
{
     void use()
     {
          System.out.print("Beep!");
     }
}

class Perfume extends Item
{
     void use()
     {
          amount -= 1;
     }
 
     int amount = 10;
}

//Compositing class.
class Bundle extends Item
{
     # held items.
     List items = new ArrayList();
 
     # this simply calls use() of each held item.
     void use()
     {
          for (Item item: items)
              item.use()
     }
}

 

Decorator Pattern

rosiejetsons

A class acts as a container and proxy for a sibling, but also defines new features to enhance it.

This sounds like the Composite pattern, but Composite intends to collect, while Decorator intends to enhance.

Example:

//Class to be decorated.
class Robot
{
     void run()
     {
           ...
     }
}

//Decorating class.
class JetBot extends Robot
{
     //robot to enhance.
     Robot robot;
     JetBot(Robot robot)
     {
          this.robot = robot;
     }

     //enhancing features.      
     int fuel = 100;

     ...
}

 

Command Pattern

An action, in the form of an algorithm, is contained in an object to remember and use the algorithm later.

Example:

abstract class Job
{
     abstract void do();
}
class CleanJob
{
     void do()
     {
          //...
     }
}
class PrintJob
{   
     void do()
     {
          //...
     }
}

 

Strategy Pattern

Different algorithms that fulfill the same goal differently are saved.

Purpose is to save actions for use in different scenarios.

Similar to Command, but Strategy algorithms are intended for one goal, while Command algorithms are for different goals.

Example:

//strategy to sort Accounts.
class AccountComparatorByName implements Comparator<Account>
{
     public int compare(Account first, Account second)
     {
          return first.name.compareTo(second.name);
     }
}
 
//another strategy.
class AccountComparatorByID implements Comparator<Account>
{
     public int compare(Account first, Account second)
     {
          return first.id – second.id;
     }
}
 
//test: make list.
List list = new List();
list.add(new Account(8152, "David"));
list.add(new Account(1372, "Shawn"));
list.add(new Account(3283, "Ruth"));
 
//try sorting strategies.
Collections.sort(list, new AccountComparatorByName());
Collections.sort(list, new AccountComparatorByID());

 

Template Method Pattern

An abstract class contains one concrete method (the “template”) that calls several abstract methods, which are defined by concrete classes.

Example:

abstract class Game
{
     //Template method.
     void play(int players)
     {
          initialize();
          while (!isEnd())
               turn();
     }

     //Abstract methods.
     abstract void initialize();
     abstract void turn();
     abstract boolean isEnd();
}

class Chess extends Game
{
     void initialize()
     {
          //...
     }
     
     void turn()
     {
          //...
     }

     boolean isEnd()
     {
          //...
     }
}

class Poker extends Game
{
     void initialize()
     {
          //...
     }
     
     void turn()
     {

          //...
     }

     boolean isEnd()
     {
          //...
     }
}

 

Factory Method Pattern

A method implements an abstract method for only creating and returning objects.

Example:

abstract class AsexualOrganism
{
     abstract Object reproduce();
}
 
class Virus extends AsexualOrganism
{
     //factory method.
     Object reproduce()
     {
          return new Virus();
     }
}

Example:

//make list.
List list = new LinkedList();
 
//create iterator by the factory method iterator().
Iterator iterator = list.iterator();
 
//iterator() implements List’s method iterator().

 

Abstract Factory Pattern

An abstract class with factory methods has several subclasses in their own object creation theme.

Example: “LookAndFeel” classes for graphical applications

 

Chain Of Responsibility Pattern

Belt-conveyor-handling

Several handlers handle a request in sequence, like workers over a conveyor belt.

Example:

//make button.
final JButton button = new JButton();
 
//make two ActionListeners handling the same event.

ActionListener one = new ActionListener() 
{
     public void actionPerformed(ActionEvent e)      
     {
           System.out.println("Clicked!");
      } 
};

ActionListener two = new ActionListener() 
{
     public void actionPerformed(ActionEvent e)      
     {
          button.setEnabled(false);
      } 
};

button.addActionListener(one);
button.addActionListener(two);

 

Memento Pattern

An object’s old state is saved (like a “snapshot”) to later return to it.

Coupled with the Command Pattern, it is a useful pattern to create undo functionality by.

Example are found in How to Implement Undo/Redo.

 

Proxy Pattern

An object acts an interface (actor on behalf) to another object, being used exactly like that other.

Examples can be found in Adapter, Composite, and Decorator sections above.

Please like & share:

Software Process

The software process is the organized process of creating software, from its inception to obsolescence.

Software engineers broke down formally the software process into five stages:

  • Analysis
  • Design
  • Implementation
  • Testing
  • Deployment

Different software methodologies integrate these stages in their own way.

 

Analysis Stage

In the first step, we identify the whys of the software: what it will accomplish. This is done by:

  • Requirements specification
  • Use Cases/Storyboarding

Requirements specification is a document that:

  1. Details the functional (specific actions done) and non-functional (system constraints) requirements of the software.
    1. Functional example: System must authenticate user prior to servicing him/her.
    2. Nonfunctional example: System must authenticate under 1 second.
  2. Translates what the business owners want out of their software product into technical specifications as reference for the project team.
  3. Is a predictor of costs, production schedules, and risks of the software.

We record the steps of hypothetical cases of using the software called use cases. Example:

  Use Case: Eating

  1. Cat opens door.

  2. Cat pushes a dispenser button.

  3. Dispenser gives food.

  4. Cat eats food.

    Variation #1:

  5. Cat cannot open door.

  6. Cat waits for customer service.

  7. Continue with step 2.

Storyboarding is basically use cases but pictorially illustrated. Example (from wiki):

776px-Storyboard_for_The_Radio_Adventures_of_Dr__Floyd

 

Design Stage

Here, we plan what classes of objects will exist in the software and what each class is responsible for. This is done with:

  • CRC cards
  • Class diagrams
  • Sequence diagrams
  • State diagrams
  • Outlines in Javadoc

CRC cards are paper index cards used to identify:

  1. Classes that will exist in your program (usually the nouns found in the analysis stage)
  2. Responsibilities of those classes, ie. the methods (usually the verbs)
  3. Collaborators of each responsibility (which other classes are involved in each method)

crccard

Class diagrams are tables showing classes, their variables and methods, and relationships between them using arrows:

RELATIONSHIP Description Arrow Human Class Example
Aggregation Has as instance/class variable, “has-a” aggregation Has Arm
Dependence Manipulates, “uses” dependence Uses Food
Inheritance Subclasses, “is-a” inheritance Is Animal
Implementation Implements interface implementation Implements Worker

Example:

372px-KP-UML-Generalization-20060325_svg

Sequence diagrams show the timeline of a typical program run, in method calls (and optionally their return values). Example:

sequencediagram

State Diagrams show a program in different states with actions between them. Example:

statediagram

Outlining in Javadoc is writing Javadoc comments before blank classes and methods (“a program skeleton”) that would be filled out in the implementation stage. Example:

/** Cat.
     @author David Hsu
*/
class Cat
{
     /** Say something.
          @param what what to say.
     */
     void say(String what)
     {
     }

     /** Sleep.
          @param minutes number of minutes to sleep.
     */
     void sleep(int minutes)
     {
     }
}

 

Implementation Stage

Here, we give substance to the design of the previous stage by means of programming code.

Implementation may only result in a prototype (“earliest-type”), meaning incomplete software, but may still be runnable and it can be built on later.

 

Testing Stage

Here, we test the implemented product in all its aspects to ensure that each works properly.

Different kinds of testing exist, including:

  • Unit – testing each module of a software separately, to ensure it is working properly.
  • Regression – re-testing a software when a new feature has been added, to ensure it broke nothing that is older.

 

Deployment Stage

Here, the software product is released to the targeted audience.

This may include both installing and configuring the product on target systems.

 

Methodologies

Methodologies have been created to involve the above software stages in different ways to suit different software, most famously:

 

Waterfall Methodology

waterfall

The software process steps are done in sequence, but no step can be returned to after finishing it.

Its disadvantage is risk, because steps are often mistaken for finished when it really isn’t.

Its advantages are simplicity (and thus manageability) and suitable use in small projects where requirements are well understood.

 

Evolutionary Methodology

The software process steps are done in order, and any of those steps can be revisited at any time, as opposed to Waterfall.

 

Spiral Methodology

spiralmodel

The waterfall model but with all the steps repeated some number of times.

The products of the first few cycles are called prototypes (“earliest types”). A user interface prototype is common for this.

 

Extreme Methodology

This is a methodology that simplifies development by removing formal practices and focusing on the “best practices”, including:

  • Minimalizing the software (removing unnecessary things)
  • Refactoring (simplifying) code
  • Conforming to readable coding standards
  • Pairing programmers for tasks
  • Re-testing the whole software whenever a new feature is added
  • Scheduling consistent work hours to stabilize progress
Please like & share:

Print shortcut

These alternative ways help print to console faster and, thus, debug and other actions faster by shorter typing:

 

  • Use the import static statement:
import static java.lang.System.out;

To print, call:

out.println(something);

 

  • Another way is to write this method in whatever class you want to print something from:
static void say(Object o)
{
     System.out.println(o);
}

This acts like a proxy method to System.out.println(), which is no different at all from it, just a shorter name (you can also choose your own name of course).

You can now print by writing:

say(something);

 

  • If you need to use this method often, you can write it inside a new, preferably with a short name, class:
class I
{
     static void say(Object o)
     {
          System.out.println(o);
     }
}

 

Hope this will increase your productivity!

Please like & share:

How to Implement Undo/Redo in Java

Undoing and redoing can be implemented in your programs by using the Command pattern. The Command pattern is a design pattern where objects represent commands. That is, objects contain some statements to be executed. These statements operate on some data to change its state.

To add undo functionality, add another set of statements changing the state of the data to the way it was before. This is easy to do and can be done in a few steps.

 

1.     Make an interface with two methods, undo() and redo().

Example:

interface UndoableCommand
 {
        void undo();
        void redo();
 }

 

2.     Create a class implementing it, which does your desired command. For example, UndoableListAdd, which undoes adding to a List. Any command you wish is acceptable, except that the data that is operated on must be mutable (that is, objects and not primitives).

Example: a class that will erase an element from an array, with what variables it should hold.

class UndoableErase implements UndoableCommand
 {
        //variables saving array, index to erase, and element.
        Object[] array;
        int index;
        Object oldval;
 }

 

3. In constructor, assign the data to instance variable(s).

Example: the constructor for my class would save array and its state details of old element and index to erase and apply erase operation (unset array slot at index). It takes an array and an index as arguments to the constructor.

        UndoableErase(Object[] array, int index)
        {
               //save the array and index to erase.
               this.index = index;
               this.array = array;
               this.oldval = array[index];
 
               //erase.
               array[index] = null;
        }

 

4. In undo(), set saved data to its old state (before the command).

Example: the undo() command for my class sets the array to old state (set element at index to old element).

        public void undo()
        {
               array[index] = oldval;
        }

 

5. In redo(), set saved data to its new state (after the command).

Example: the redo() for my class would set the array to new state (unset array slot at index).

        public void redo()
        {
               array[index] = null;
        } 

(Note: executing the command is the same as calling redo())

My example put together looks like this:

class UndoableErase implements UndoableCommand
 {
        //fields saving array, index to erase, and element.
        Object[] array;
        int index;
        Object oldval;
 
        UndoableErase(Object[] array, int index)
        {
               //save the array and index to erase.
               this.index = index;
               this.array = array;
               this.oldval = array[index];
 
               //erase.
               array[index] = null;
        }
 
        public void undo()
        {
               array[index] = oldval;
        }
 
        public void redo()
        {
               array[index] = null;
        }
 }

The tester for my example looks like this:

class Tester
{
    public static void main(String[] args)
    {
         //make array.
         Object[] array = new Object[] {1, 2, 3};
 
         //apply operation on it.
         UndoableOp op = new UndoableErase(array, 1);
         System.out.println(Arrays.toString(array)); //[1, null, 3]
 
         //undo that.
         op.undo();
         System.out.println(Arrays.toString(array)); //[1, 2, 3]
 
         //redo that.
         op.redo();
         System.out.println(Arrays.toString(array)); //[1, null, 3]
     }
}
Please like & share:

Enumerators

Enumerators are symbols (like DIME, NICKEL) used to represent values, which values cannot be represented well by other types like int or boolean.

Enumerator types are limited in values (just like how type boolean has only 2 values).

Enumerators are Objects that are set by the compiler to be non-modifiable.

Purpose is for keeping your code readable and therefore less buggy.

 

Enumerator Definition

enum Enumerator
{
     value1, value2, 
}

This creates an enumerator called Enumerator, with values (and only those values).

Enumerators cannot be modified after definition.

Example:

enum Status
{
     SINGLE, MARRIED
}

 

Testing for equals

Enumerators can be tested for equals just like how booleans can, too.

Example:

Status status = Status.SINGLE;
if (status == Status.SINGLE)
     return;
Please like & share:

Graphical Interfaces

Nimbus_Normal

Graphical User Interfaces (GUI) are visible menus you can interact with.

Purpose is for taking input from users or pop up info to them.

Graphic objects are found in the swing folder of the built in Java files.

A recommended way to build graphical interfaces is to use Netbeans, which builds these interfaces faster by using a visual editor that also automatically generates your code.

 

Making a window

UDD_Java_Frame

Use the JFrame class to create a window.

Show this window by using the method setVisible(True).

Example:

JFrame frame = new JFrame("title"); //create frame with title
frame.setVisible(true); //show frame

Set its size by setSize(), or pack() to set it to whatever size its contents take. Example:

frame.setSize(100, 100); //size it 100 pixels width, 100 pixels height
frame.pack(); //pack it down to its contents

 

Adding components

add(component);

This adds graphical objects into one another.

Every object in the swing folder is a Container, which means they can be contained in one another.

Example:

JFrame frame = new JFrame();
JLabel label = new JLabel("label"); //make label
frame.add(label); //add it to frame
frame.pack();
frame.setVisible(true);

 

Positioning components

Add_JToggleButton_to_each_part_of_a_border_layout_in_Java_Example

Classes inheriting LayoutManager (from java.awt package) help you position component positions more precisely:

LayoutManager Description
AbsoluteLayout Absolute positioning of objects given by coordinates
BorderLayout (JFrame default) Separates container into 5 areas: center, north, west, south, and east
BoxLayout Bottom to top layout
CardLayout Creates layers of panels where each can be brought to front by an action
FlowLayout (JPanel default) Left to right layout
Group Layout Groups containers; designed for use by visual editors like NetBeans
GridLayout Arranges components in a grid, each same sized, with a fixed number of rows and columns
GridBagLayout Like Grid Layout, but columns can have different sizes, and one component can span multiple columns
null No layout; each object needs to set their own rectangular bounds to show up correctly
OverlayLayout Back to front layout (overlapping objects)

Use setLayout() method to change the layout.

Example:

JFrame frame = new JFrame(); //make window
frame.setLayout(new GridLayout()); //set to grid layout
List list = new ArrayList();
for (int i = 0; i < 5; i++) //make list of buttons
        list.add(new JButton("test"));
for (JButton button : list) //add buttons to window
        frame.add(button);
frame.pack(); //auto-size window
frame.setVisible(true); //show window

 

ActionListeners

Button-Listener-Window

ActionListeners are objects that listen for a trigger in a component and run a list of statements when it is triggered.

ActionListeners implement the ActionListener interface.

Each component has a unique trigger:

Component Trigger
JButton Clicked
JComboBox An option is clicked
JRadioButton Clicked
JCheckBox Clicked
JTextBox Pressed enter when focused
JToggleButton  Clicked

To make a customized ActionListener with your own statements to run, make a new class implementing it and write your statements in the inherited method actionPerformed(). Example:

class Listener implements ActionListener
{
     public void actionPerformed(ActionEvent event)
     {
          //statements run when component is triggered
     }
}

Then call this method from a component to add an ActionListener to a component.

addActionListener(listener);

Example:

class Listener implements ActionListener
{
     public void actionPerformed(ActionEvent event)
     {
          System.out.println(“Triggered!”); //print something
     }
}
class Tester
{
     public static void main(String[] args)
     {
          JFrame frame = new JFrame(); //make window
          JButton button = new JButton(“click me”); //make button
          button.addActionListener(new Listener()); //add new listener
          frame.add(button); //add it to frame
          frame.pack();
          frame.setVisible(true);
     }
}
Common Error: forgetting to add an ActionListenerActionListener-less objects do nothing when you click on them, so beware that you do not forget them.
Please like & share:

Generics

Generics are classes, interfaces, methods, or constructors that use special variables called type variables.

ArrayList is an example of a generic class.

 

Type Variables

These are special variables that can be assigned types (the variables we normally use can be called value variables, because they are assigned values).

Purpose is to be used to declare value variables.

Example:

type var; //if type is a type variable, var will be declared with that type

 

Generic Class Definitions

class Class<type>
{
     ...
}

This creates a class with a type variable named type.

Type variables are accessible within the body, like how normal variables are.

Example:

//box that holds contents of a type.
class Box<type>
{
     type contents;
     Box(type contents)
     {
          this.contents = contents;
     }
}

Variables assigned generic class objects are declared and instantiated with angle brackets, having types to be passed to the constructor. Example (try it):

Box<String> stringbox = new Box<String>(“string”);

 

Generic Method Definitions

<type, type2, ...> return-type method()
{
     ...
}

This defines a method with type variables type, type2, ….

To be able to pass types to the method, make parameters preceded by type variables and write those type variables inside angle brackets.

Example:

<type> boolean equals(type a, type b)
{
     return a == b;
}

Modifiers (like static, public, etc.) must go before the angle brackets.

 

Constraining type variables

<type extends another-type>

This constrains what type can be to only types that extend another-type.

Example:

//test whether two Number values are identical.
<type extends Number> void test(type a, type b)
{
     System.out.println(a == b);
}

One can also use the keyword super to limit the type to be parent of another-type:

<type super another-type>

If you do not need to know nor use the passed type, you can change type to ? instead, for simplifying purposes:

<? super another-type> //cannot know ?

 

Naming conventions

I made my own names for type parameters in simplicity, like “type”. But these are the usual names people give to type parameters:

  • E – Element (used extensively by the Java Collections Framework)
  • K – Key
  • N – Number
  • T – Type
  • V – Value
  • S,U,V etc. – 2nd, 3rd, 4th types
Please like & share:

Maps

mapping

Maps are objects that hold values like ArrayLists, but their values can be indexed by objects instead of just integers.

The indexing set of objects is called the keys. The indexed set of objects is called the values.

Import from java.util.Map from the built-in Java library to use Map.

 

Creating Maps

Map map = new Map-type();

This creates a map of Map-type but used as Map. Map is an interface, so it cannot be instantiated, so another class must implement it, which we’ll call Map-type.

Here, map accepts both keys and values as Objects.

Map-type can be the following:

  • java.util.HashMap – Uses a special technique called hashing for faster indexing.
  • java.util.TreeMap – Automatically sorts elements in a given order as they are added.
  • And more, but these are the most used ones

Example:

Map map = new HashMap();

 

Constraining types

Map<KeyClass, ValueClass> map = new Map-type<KeyClass, ValueClass>();

This creates a map called map and limits the types of accepted keys to KeyClass, and the types of accepted values to ValueClass.

Example (try it):

Map<String, Integer> map = new HashMap<String, Integer>();
map.put("price", 10);
map.put("quantity", 5);

 

Adding Associations

map.put(key, value)

This associates key to value in map.

Keys cannot be duplicate, but values can.

The associations are represented by the class Entry.

Example (try it):

map.put("key", "value");

 

Retrieving values

map.get(key)

This retrieves the value associated to key.

The returned value will be of the declared type for map’s values (if no type was declared, it returns an Object).

Example (try it):

System.out.println(map.get("key")); //prints "value"

 

Retrieving Keys

Use the method keySet() to retrieve a set of keys (of class Set).

Then you can call toArray() to retrieve the keys in an Array.

Example (try it):

Set set = map.keySet();
set.toArray();

 

Sorting by Keys

We do this several ways, each needing an implementation of the Comparator interface, like so:

class KeyComparator implements Comparator
{
    public int compare(Object a, Object b) 
    {
        if ((char) a > (char) b)
             return 1;
        else
             return -1;
    }
}

Then we can:

  • Use Treemap from the very beginning, which sorts entries as they are added (try it):
Map map = new TreeMap(new KeyComparator());
map.put('B', 3);          
map.put('A', 1);
map.put('C', 2);
  • Or make a TreeMap out of your unsorted map, which automatically sorts it (try it):
Map sortedmap = new TreeMap(new KeyComparator());
sortedmap.putAll(map);
  • Or sort a copy of the key list and extract each association by that sorted key order, like so (try it):
  //make map.
  Map map = new HashMap(); 
  map.put('B', 3);          
  map.put('A', 1);
  map.put('C', 2);
  
  //get keylist and sort it.
  List keylist = new ArrayList(map.keySet());
  Collections.sort(keylist, new KeyComparator());
  
  //extract associations and put in a new map.
  Map sortedmap = new HashMap();
  for (Object key: keylist)
       sortedmap.put(key, map.get(key));

 

Sorting by Values

One way to do this is putting your unsorted map into a new TreeMap, passing a comparator to it.

Difference from KeyComparator above is that this comparator must remember the map.

Example (try it):

import java.util.*;

class ValueComparator implements Comparator
{
     Map map;
     ValueComparator(Map map) 
     {
         this.map = map;
     }

     public int compare(Object a, Object b) 
     {
         if ((double) map.get(a) > (double) map.get(b)) 
             return 1;
         else 
             return -1;
     }
}

class Tester
{
     public static void main(String[] args) 
     {
         //make map.
         Map map = new HashMap(); 
         map.put("Beltre", .324);
         map.put("Martinez", .335);
         map.put("Alluve", .341);
         map.put("Brantley", .327);
         System.out.println("Unsorted: " + map);

         //put in a TreeMap.
         Comparator comparator = new ValueComparator(map); 
         Map sortedmap = new TreeMap(comparator);
         sortedmap.putAll(map);
         System.out.println("Sorted: " + sortedmap);
     }
}

A comparator is not truly needed if comparing strings, characters, or numbers, as Java knows how to sort them, but I used one for demonstration purposes.

Please like & share:

Error Handling

Errors in Java are represented by objects holding error information.

These objects are generated when errors occur.

Errors are handled by a programmer’s statements and these error objects.

 

Handling Errors

try
{
     statements
}
catch(Throwable-type error)
{
     statements
}

In the above, the try{} block tries to run statements that can err.

The catch{} block catches its errors and handles them with statements.

Example (try it):

try
{
     int x = 1 / 0; //generate an error here
}
catch (ArithmeticException error) //catch it
{
      System.out.println(error);
}

 

Throwing Errors

method() throws Throwable=type
{
     ...
}

When you do not want to handle an error, you can throw it.

throws reserved word throws (passes off) all of a type of error that happens in a block to the calling method of the currently running method to handle it.

No try block is needed in the throwing method.

The calling method must either catch it or throw it again (think “hot potatoes”).

Example:

class Tester
{
       static void err() throws ArithmeticException //erring method
       {
              int x = 1 / 0;
       }
 
       static void catchError() //calls above and catches its error
       {
              try
              {
                     err();
              }
              catch (ArithmeticException error)
              {
                                   System.out.println(error); //prints “/ zero” error

              }
       }
 
       public static void main(String[] args)
       {
                        catchError();

       }
}

 

Checked & Unchecked

Blue - checked Red - unchecked

Some of the most well-known errors. Blue – checked, red – unchecked

Checked errors (meaning “errors checked by compiler”) are errors that are required by the compiler to be handled, or your program will terminate.

Unchecked errors are errors that do not need to be handled or are fatal (which cannot be handled anyway).

 

Finally

finally
{
     statements
}

Finally blocks follow try/catch blocks and are run right after them.

They are blocks that run no matter what happens.

Purpose is to ensure something is run right before the program would terminate on an error (but it still will terminate afterwards).

They are often used for ensuring a file is closed when working on a file.

 

Assertions

assert expression;

This statement requires that some expression evaluates to true, else the program creates an AssertionError that must be caught or the program terminates.

This AssertionError is only created if the assertion feature is enabled in the compiler that you are using.

Purpose is to help detect errors in your program.

Example:

 

int divide(int x, int y)
{
     assert y != 0;

     return x / y;
}

 

 

Creating your own Error type

Your can make your own error classes, which must subclass Throwable.

Two types of Throwable already exist:

  • Error, which represents errors so severe they are not often handled.
  • Exception, which is often handled and includes errors that do or do not need to be handled.

Example:

class NewError extends Throwable
{
}
class Tester
{
    public static void main(String[] args)
         {
              try
              {
                   if (true == true)
                        throw new NewError();
              }
              catch(NewError error)
              {
                                  System.out.println("got here");

              }
       }
}
Please like & share: