Home | FAQ | Contact me

Generics—a third example

Even after a few years writing principally in Java, I struggle to master the finer points of this topic. Here's an example to help.

package com.windofkeltia;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.junit.runners.MethodSorters;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

@FixMethodOrder( MethodSorters.NAME_ASCENDING )
public class GenericsTest
{
  @Before public void setUp() { buildPojoList(); }

  private List< Pojo > pojoList;

  @Test
  public void testWalkAllPojos()
  {
    System.out.println( "Walk all the POJOs in our list:" );
    for( Pojo pojo : pojoList )
      System.out.println( "[" + pojo.getClass().getSimpleName() + "] " + pojo.toString() );
  }

  /** Extract a patient POJO from the list. */
  @Test
  public void testExtractTheFirstPatient()
  {
    Patient patient = ( Patient ) extractPojo( Patient.class, pojoList );
    assertTrue( patient instanceof Patient );
    System.out.println( "Found patient " + patient.toString() );
  }

  /** Extract the list of address POJOs (there are multiple) from the list. */
  @Test
  public void testExtractAllAddressPojos()
  {
    List< Address > addresses = extractPojos( Address.class, pojoList );
    assert addresses != null;
    assertEquals( addresses.size(), 2 );
    System.out.println( "Found addresses:" );
    for( Address address : addresses )
      System.out.println( address.toString() );
  }

  /** Extract a reference to the first POJO of the given type from the list. */
  public static Pojo extractPojo( Class< ? extends Pojo > clazz, List< Pojo > pojoList )
  {
    for( Pojo pojo : pojoList )
    {
      if( pojo.getClass() == clazz )
        return pojo;
    }

    return null;
  }

  /** Create a list of references of the given type extracted from the list. */
  public static < T > List< T > extractPojos( Class< T > clazz, List< Pojo > pojoList )
  {
    List< T > pojos = new ArrayList<>();

    for( Pojo pojo : pojoList )
    {
      if( pojo.getClass() == clazz )
        pojos.add( ( T ) pojo );
    }

    return( pojos.size() > 0 ) ? pojos : null;
  }

  private void buildPojoList()
  {
    pojoList = new ArrayList<>();
    pojoList.add( new Address( "3620 Bedford Drive", "Missoula" ) );
    pojoList.add( new Telephone( "801 295-9626", "home" ) );
    pojoList.add( new Patient( "Jim", "Davis" ) );
    pojoList.add( new Address( "568 Mulberry Avenue", "Pottersville" ) );
    pojoList.add( new Patient( "Bill", "Watterson" ) );
  }

  static class Pojo
  {
    long x = System.currentTimeMillis();
  }

  static class Address extends Pojo
  {
    String street;
    String city;

    public Address( String street, String city )
    {
      super();
      this.street = street;
      this.city   = city;
    }

    public String toString() { return street + ", " + city; }
  }

  static class Telephone extends Pojo
  {
    String number;
    String type;

    public Telephone( String number, String type )
    {
      super();
      this.number = number;
      this.type   = type;
    }

    public String toString() { return number + " (" + type + ")"; }
  }

  static class Patient extends Pojo
  {
    String firstname;
    String lastname;

    public Patient( String firstname, String lastname )
    {
      super();
      this.firstname = firstname;
      this.lastname  = lastname;
    }

    public String toString() { return  firstname + " " + lastname; }
  }
}

Output:

Test: testWalkAllPojos ------------------------------------------------------------------------------------
Walk all the POJOs in our list:
[Address] 3620 Bedford Drive, Missoula
[Telephone] 801 295-9626 (home)
[Patient] Jim Davis
[Address] 568 Mulberry Avenue, Pottersville
[Patient] Bill Watterson

Test: testExtractTheFirstPatient --------------------------------------------------------------------------
Found patient Jim Davis

Test: testExtractAllAddressPojos --------------------------------------------------------------------------
Found addresses:
3620 Bedford Drive, Missoula
568 Mulberry Avenue, Pottersville