References Example


/* This is a primitive */
int x = 127;

/* This is a reference */
String s = new String("Hello");

Arrays are Reference Types


/* This is an array */
int[] x = {5,7,8};

Using == on references


/* What do you think this does? */
Date date1 = new Date(2018, 6, 14);
Date date2 = new Date(2018, 6, 14);

if(date1 == date2){
  System.out.println("They are the same!");
}

Using == on references


/* These two vars are NOT == */
Date date1 = new Date(2018, 6, 14);
Date date2 = new Date(2018, 6, 14);

if(date1 == date2){
  System.out.println("They are the same!");
}

Comparing references


/* These two vars are NOT == */
Date date1 = new Date(2018, 6, 14);
Date date2 = new Date(2018, 6, 14);

/* Use .equals() to compare references */
if(date1.equals(date2)){
  System.out.println("They are the same!");
}

Assignment of References


Date date1 = new Date(2018, 6, 14);
Date date2 = new Date(2018, 7, 18);

date1 = date2;

System.out.println(date1);

Assignment of References


Date date1 = new Date(2018, 6, 14);
Date date2 = new Date(2018, 7, 18);

date1 = date2;

System.out.println(date1);

Before the assignment

Assignment of References


Date date1 = new Date(2018, 6, 14);
Date date2 = new Date(2018, 7, 18);

date1 = date2;

System.out.println(date1);

AFTER the assignment

Shared References


/* From previous slide */
/* Note that BOTH date1 and date2 are changed */
date1.setYear(2017)

Another Example of References


/* From previous slide */
/* Note that date1 is not affected here */
date2 = new Date(2013, 10, 28);

    public static void swap(int num1, int num2){
      int temp = num1;
      num1 = num2;
      num2 = temp;
    }
    public static void main(String args[]) {
        int x1 = 5; int x2 = 7;
        swap(x1,x2); //<--Code is here
    }

    public static void swap(int num1, int num2){
      int temp = num1; //<--Code is here
      num1 = num2;
      num2 = temp;
    }
    public static void main(String args[]) {
        int x1 = 5; int x2 = 7;
        swap(x1,x2);
    }

    public static void swap(int num1, int num2){
      int temp = num1;
      num1 = num2;
      num2 = temp; //<--Code is here
    }
    public static void main(String args[]) {
        int x1 = 5; int x2 = 7;
        swap(x1,x2); 
    }

    public static void swap(int num1, int num2){
      int temp = num1;
      num1 = num2;
      num2 = temp;
    }
    public static void main(String args[]) {
        int x1 = 5; int x2 = 7;
        swap(x1,x2); //<--Code returns here
    }

    Point x1 = new Point(1,2); Point x2 = new Point(5,6);
    swap(x1,x2);

    public static void swap(Point p1, Point p2){
      Point temp = p1;  //CODE IS HERE
      p1 = p2;
      p2 = temp;                               }

    public static void swap(Point p1, Point p2){
      Point temp = p1;
      p1 = p2;
      p2 = temp;  //CODE IS HERE               }

    Point x1 = new Point(1,2); Point x2 = new Point(5,6);
    swap(x1,x2); //Method returns, no change in x1 or x2

    Point x1 = new Point(1,2); Point x2 = new Point(5,6);
    swap(x1,x2); //About to invoke swap

  public static void swap(Point p1, Point p2){
      Point temp = (Point)p1.clone(); //Deep Copy
      p1.x = p2.x; p1.y = p2.y;
      p2.x = temp.x; p2.y = temp.y;
  }

  public static void swap(Point p1, Point p2){
      Point temp = (Point)p1.clone(); //<-- This line Executed
      p1.x = p2.x; p1.y = p2.y;
      p2.x = temp.x; p2.y = temp.y;          
  }

  public static void swap(Point p1, Point p2){
      Point temp = (Point)p1.clone(); 
      p1.x = p2.x; p1.y = p2.y;  //<-- This line Executed
      p2.x = temp.x; p2.y = temp.y;
  }

  public static void swap(Point p1, Point p2){
      Point temp = (Point)p1.clone(); 
      p1.x = p2.x; p1.y = p2.y;
      p2.x = temp.x; p2.y = temp.y; //<-- This line Executed
  }

    Point x1 = new Point(1,2); Point x2 = new Point(5,6);
    swap(x1,x2); //Swap has returned

    Card c1 = new Card(); //Ace of spades by default
    Card c2 = new Card(3, "Diamonds"); //3 of diamonds
    System.out.println(c1.toString());
    System.out.println(c2.toString());

Accessing Fields


    Card c1 = new Card(); //Ace of spades by default
    Card c2 = new Card(3, "Diamonds"); //3 of diamonds
    c1.rank = 3; //just changed card into rank 3
    c1.suit = "Diamonds"; //now c1 is a diamond
    System.out.println(c1.toString());
    System.out.println(c2.toString());

Checking Equality


    /* Code from previous slide(s) */
    if(c1 == c2)
      System.out.println("This won't happen!");

    /* Won't work because Card class needs an equals() method */
    if(c1.equals(c2))
      System.out.println("This should happen, but won't")

Equality of cards

 
public class Card{
  /* From previous slide Card class slide */

  /* Checks for equality of two cards */ 
  public boolean equals(Object other) {
    Card otherC = (Card)other;
    return    otherC.rank == this.rank
           && otherC.suit.equals(this.suit);
  }
}

Enums

 
/* An Enum is a variable type that has a finite set of values */
/* Let's use one for the suit of a card */
public enum Suit{
    Hearts, Diamonds, Spades, Clubs; 
  }

Using the enum in the Card class

 
public class Card{
  int rank; //1 (Ace) through 13 (King)
  Suit suit; //"Spades", "Hearts", "Clubs", "Diamonds"

  /* Default constructor. Ace of Sp. is default card */
  public Card() {
    this.rank = 1;
    this.suit = Suit.Spades;
  }
  
  /*
   * Constructor. Allows you to set the cards data when
   * creating it. This is called overloading a method
   */
  public Card(int rank, Suit suit) {
    this.rank = rank;
    this.suit = suit;
  }
  
  /**
   * This is a method, will return a description
   * of this card as a String 
   */
  public String toString() {
    String rank = "";
    switch(this.rank) {
      case 1:
        rank = "Ace";
        break;
      case 11:
        rank = "Jack";
        break;
      case 12:
        rank = "Queen";
        break;
      case 13:
        rank = "King";
        break;
      default:
        rank = "" + this.rank; //number and rank the same
        break;
    }
    
    return rank + " of " + this.suit;   
  }
  
  @Override
  public boolean equals(Object other) {
    Card otherC = (Card)other;
    return otherC.rank == this.rank && otherC.suit == this.suit;
  }
}

Updating the Card class

 
public Class Card{ 
  private int rank; //1 (Ace) through 13 (King)
  private Suit suit; //"Spades", "Hearts", "Clubs", "Diamonds"

  /* Default constructor. Ace of Sp. is default card */
  public Card() {
    this.rank = 1;
    this.suit = suit.Spades;
  }
  
  /*
   * Constructor. Allows you to set the cards data when
   * creating it. This is called overloading a method
   */
  public Card(int rank, Suit suit) {
    this.rank = 1; // in case setRank fails
    this.setRank(rank);
    this.suit = suit;
  }
  
  public int getRank() { return this.rank; }
  public Suit getSuit() { return this.suit; }
  
  public void setRank(int newRank) {
    /* Ignore if trying to set to illegal value */
    if(newRank < 1 || newRank > 13) return;
    
    /* Otherwise, set it */
    this.rank = newRank;
  }
  public void setSuit(Suit newSuit) {
    /* No stress, enum already must have valid value */
    this.suit = newSuit;
  }

  /* Other stuff here */
}

A more advanced class

 
public class Deck {
  
  /*private: Others cannot change the deck directly*/
  private Card[] deck;
  private int top = 0; //Top of the deck
  
  public Deck() {
    deck = new Card[52]; //deck has 52 cards
    
    /* Instantiate each individual card */
    int i = 0;
    for(int r = 1; r <= 13; r++) {
      for(Suit s : Suit.values()) {
        deck[i] = new Card(r, s);
        i++;
      }
    }
    
    /*Shuffle the deck*/
    shuffle();
  }
  
  /**
   * Shuffles the deck
   */
  public void shuffle() {
    top = 0;
    
    for(int i = 0; i < 51; i++) {
      /*Get a random position between i and 51*/
      int r = (int)(Math.random()*(52-i))+i;
      
      /* Swap card i with that card */
      Card temp = deck[i];
      deck[i] = deck[r];
      deck[r] = temp;
    }
  }
  
  /* Deals the top card, indices < top are not in the deck */
  /* Simulates this by moving the top pointer */
  public Card dealTopCard() {
    if(top <= 51) {
      top++;
      return deck[top-1];
    }
    else {
      System.out.println("ERROR: DEALING FROM AN EMPTY DECK");
      return null;
    }
    
  }
}