Journal
satya - 8/3/2018, 8:29:39 AM
Casting generic types in Java generics
Casting generic types in Java generics
satya - 8/3/2018, 8:49:46 AM
Good read on restrictions on generics: Java docs
satya - 8/3/2018, 8:50:05 AM
A quick code segment
/*
    * Understant type casting of generics
    * Due to the nature of a single class instance
    */
   private void test7()
   {
      GenericPair<Integer, Integer> intPair = 
            new GenericPair<Integer, Integer>(4,5);
      GenericPair<String, String> stringPair = 
            new GenericPair<String, String>("4","5");
      
      
      GenericPair<Integer, Integer> intPair1;
      GenericPair<String, String> stringPair2;
      
      Object stringPairObject = stringPair;
      Object intPairObject = intPair;
      
      intPair1 = (GenericPair<Integer, Integer>)intPair;
      
      //Compiler error: Makes sense two different types
      //intPair1 = (GenericPair<Integer, Integer>)stringPair;
      
      //Succeeds at compile time and run time
      intPair1 = (GenericPair<Integer, Integer>)stringPairObject;
      intPair1 = (GenericPair)stringPair;
      
      //fails at run time as getFirst() returns a string
      //tries to convert it to an int
      //int first = intPair1.getFirst();
      
      System.out.println("Test7");
   }
satya - 8/6/2018, 2:00:27 PM
what is ::new in java
what is ::new in java
satya - 8/6/2018, 2:05:58 PM
Here is a broader discussion on :: syntax at SOF
satya - 8/6/2018, 2:07:08 PM
Method references are documented here
satya - 8/6/2018, 2:38:06 PM
Lambda expression trail on oracle is here
satya - 8/6/2018, 3:57:28 PM
Collections framework is documented here
satya - 8/7/2018, 8:59:53 AM
Static method reference
Type::staticMethod()
//Example
	private void test4()
	{
		List<Person> peopleList = Person.createRoster();
		peopleList.sort(Person::compareByAge);
		System.out.println("Test4: sorted by age:" + peopleList);
	}
//In Person class
    public static int compareByAge(Person a, Person b) {
        return a.birthday.compareTo(b.birthday);
    }
satya - 8/7/2018, 9:02:47 AM
Instance method reference: (Type::instanceMethod)
Type::instanceMethod()
//Example
   /*
    * Method reference by an instance method: (Type::instanceMethod) 
    * It is an instance method
    * but no object is around
    * it assumes any arbitrary object
    * Notice how this instance method takes only one argument
    */
   private void test5()
   {
      List<Person> peopleList = Person.createRoster();
      peopleList.sort(Person::instMethodCompareByAge);
      System.out.println("Test5: sorted by age:" + peopleList);
   }
//In the Person class
//Notice the single argument 
public int instMethodCompareByAge(Person b)
{
   return birthday.compareTo(b.birthday);
}
satya - 8/7/2018, 9:11:37 AM
Instance method reference based on an arbitrary object: (Object::instanceMethod)
Object::instanceMethod()
//Example
   private void test6()
   {
      Person anyPerson = Person.createFred();
      List<Person> peopleList = Person.createRoster();
      peopleList.sort(anyPerson::instUtilityMethodCompareByAge);
      System.out.println("Test6: sorted by age:" + peopleList);
   }
//In Person class
//Notice 2 arguments as if it is static method
//Also implies usually such a method stays
//outside in a utility object instance
    public int instUtilityMethodCompareByAge(Person a, Person b)
    {
       return a.birthday.compareTo(b.birthday);
    }
satya - 8/7/2018, 9:13:22 AM
You can find some of these samples on Github here
satya - 8/7/2018, 9:36:00 AM
Lets talk about ::new now
Lets talk about ::new now
satya - 8/7/2018, 9:36:22 AM
Consider the Person constructor from above
Person(String nameArg, LocalDate birthdayArg,
            Sex genderArg, String emailArg) {
            name = nameArg;
            birthday = birthdayArg;
            gender = genderArg;
            emailAddress = emailArg;
        }
satya - 8/7/2018, 10:40:15 AM
The following is likely true
//Consider these constructors on a Type
constructor()
constructor1(arg1)
constructor2(arg1,arg2)
//will match
IFunction() -> constructor()
IFunction1() -> constructor1(arg1)
IFunction2() -> constructor2(arg1,arg2)
//One Type
//Many functional interfaces
satya - 8/9/2018, 5:14:26 PM
Here is a functional interface to represent that constructor
@FunctionalInterface
public interface FIPersonCreator {
   public Person get(String nameArg, LocalDate birthdayArg,
                  Sex genderArg, String emailArg); 
}
satya - 8/9/2018, 5:15:50 PM
It is then used as
public static Person createFredWitFI() {
       
       //Get a function pointer to a suitable constructor
       FIPersonCreator pcFi = Person::new;
       
       //Notice the get function
        return pcFi.get(
              "Fred",
              IsoChronology.INSTANCE.date(1980, 6, 20),
              Person.Sex.MALE,
              "[email protected]");
    }
satya - 8/10/2018, 9:58:30 AM
Notice a better function to create Persons
@FunctionalInterface
public interface FIPersonCreatorExperimental {
   public Person get(String nameArg, LocalDate birthdayArg,
            Sex genderArg, String emailArg); 
   default FIPersonCreatorExperimental afterThat(Consumer<Person> inCp)
   {
      //These local variables are kept with the return function
      //like a closure!!
      
      //Remember who you are
      FIPersonCreatorExperimental original = this;
      
      //To test maintenance of scope
      String testString = "hello";
      
      //To pass the person object back to the caller's desire
      Consumer<Person> cp = inCp;
      
      //Return an encapsulated function
      //that adheres to the same interface
      //this is at core interception
      return   (String nameArg, LocalDate birthdayArg,
            Sex genderArg, String emailArg) -> {
            Person p = original.get(nameArg, birthdayArg, genderArg, emailArg);
            inCp.accept(p);
            System.out.println("Inner stuff: " + testString);
            return p;
      };
   }
}//eof-class
satya - 8/10/2018, 10:00:44 AM
See how this constructor is used
//To test default methods that can be used
   //to intercept or alter the original behavior.
   private void test8()
   {
      //Get a function that can create a person
      FIPersonCreatorExperimental fip = (Person::new);
      
      //What do you want once the person is created
      //say that
      Consumer<Person> cp = (p) -> {
         System.out.println("From Test8: " + p);
      };
      
      //Now you can do this
      //Notice that the person is printed
      //every time it is created
      Person person = createPerson(fip.afterThat(cp));
      System.out.println("From Test8: at the end:" + person);
      
      //afterThat returns the same interface as "fip"
      //and hides the original "fip" in the belly
   }
   
   private Person createPerson(FIPersonCreatorExperimental creator)
   {
      return creator.get("Fred",
              IsoChronology.INSTANCE.date(1980, 6, 20),
              Person.Sex.MALE,
              "[email protected]");
   }
satya - 8/10/2018, 10:21:55 AM
Default methods, here, return lambda functions of the same signature, like a camouflage
Default methods, here, return lambda functions of the same signature, like a camouflage
