Sunday, October 28, 2018

Do you know - Series - 4: Boxing and Unboxing - Integer assignment and comparison

We know about boxing and unboxing in Java. It is about automatic conversion of primitive type value into its Wrapper Object equivalent type value and viz.

Below is the simple example to understand this.

      int a = getCustomerNumber(); //getCustomerNumber() returns an int
      Integer aObj = a; //boxing

      Integer bObj = getAccountNumber(); //getAccountNumber() returns an Integer
      int b = bObj; //unBoxing

      if(a == bObj) {
            System.out.println("a and bObj are equal");
      } else {
           System.out.println("a and bObj are not equal");
      }

The above code will work fine if the method getAccountNumber() returns an Integer value. But, the problem starts when this getAccountNumber() method returns a null value. When it returns null you could see a NullPointerException in line where we have "int b = bObj;". The reason is that we are trying to set 'null' into a primitive type.

The simplest solution to fix this is change the type of b into Integer or you may need to check for the 'null' value from the getAccountNumber() and then assign proper 'int' value to 'b'.

Now, the corrected statement will be

Integer b = bObj;


Great! We fixed the issue.

Now, when you try to run again and you would notice the same exception, but in line where we have the if() condition. Again, the reason is comparing 'null' with primitive type variable 'a'. Now, to fix this you may suggest to change the type of 'a' into 'Integer' or simply typecast 'a' into Integer within the if() condition as below.

if((Integer)a == bObj)


Excellent! We fixed the second issue!

But, things are not settled down still. If you notice the 'if()' condition we have  '==' to compare reference types. Definitely, this is not the right way to compare references, right?

Lets change the condition with if(((Integer)a).equals(bObj)) .

Finally, we are able to run the code. The final version of code section is given below.

      int a = getCustomerNumber(); //getCustomerNumber() returns an int
      Integer aObj = a; //boxing

      Integer bObj = getAccountNumber(); //getAccountNumber() returns an Integer
      Integer b = bObj;

      if(((Integer)a).equals(bObj)) {
            System.out.println("a and bObj are equal");
      } else {
           System.out.println("a and bObj are not equal");
      }


We now understand that things look simple externally, but they come with some complexities internally...


Do you know - Series - 3: Arrays as List: Java

Mose of the time we use the method Arrays.asList(T… a) to covert an array into a List. But, what we forget is that the returned list is not modifiable. It will be a fixed list backed up by the given array of elements.

This fixed list won't stop you using the method add(), to add an element to the list and remove(), to remove an element at a particular index, but will throw UnSupportedOperationException at runtime.

If you look at the Arrays class it has its own implementation of ArrayList and that is what returned by the asList() method. Though the ArrayList class extends the AbstractList, but does not override the add() and remove() methods which is actually the reason for the UnSupportedOperationException.

So, the use of Arrays.asList(T… a) is to just get an readonly List from an array of elements. It just acts a bridge between array and collection based APIs.

If you need a modifiable List then you may wrap this unmodifiable list into an ArrayList as given in the below sample code.

public List getList(String[] array) {
    List unModifiableList = Arrays.asList(array);
    unModifiableList.add("abc"); //not supported
    unModifiableList.remove(1); //not supported
 
    List modifiableList = new ArrayList(unModifiableList); //wrapper to read-only list
    modifiableList.add("abc"); //supported
    modifiableList.remove(1);  //supported
}

Monday, September 3, 2018

Do you know - Series 2: Stream Operation: Java

This post talks about different options available for iterating over a List.

  • using iterator  - Jdk 1.2
          List listItems = new LinkedList();
          listItems.add("a");
          . . .
          listItems.add(n);
          Iterator itr = listItems.iterator();
          while(itr.hasNext()) {
                String item = itr.next();
                doSomething(item);
         }

  • using for loop - Jdk 1.5
          for(String item: listItems) {
                 doSomething(item);
          }
  • using for...each loop - Jdk 1.8
          listItems.forEach(item -> doSomething(item));
  • using Streams  - Jdk 1.8
          listItems.stream().filter(something).map(item -> doSomething(item)).count();
          or
          Stream.of("a", "b", "c").filter(something).map(item -> doSomething(item)).count();

Please note that the Streams can not be reused once it is done with any terminal    operations.  When you try to reuse you will get IlleagalStateException as the stream is already operated and closed. 

If you want to reuse and avoid this exception then you may keep the above statement local scope or create a new stream every time using stream Supplier as below.
     
          Supplier < Stream < String >> streamSupplier = () -> Stream.of("a", "b", "c");
          

                  

Sunday, September 2, 2018

Do you know - Series 1: Null Check: Java


The idea of this post is to just highlight some of the features in Java which we may need in our day to day development work.

  • The different ways to check null value of an Object
    • null != obj
    • Objects.nonNull(obj) - from java.util
    • filter(Objects::nonNull) - when used with Lambda
    • Optional.ofNullable(obj).ifPresent(o —> o.getValue());
    • StringUtils.isNotEmpty(obj) - froorg.apache.commons.lang3
      • this takes care of both empty and null checks
    • filter(StringUtils::isNotEmpty) - when used with Lambda

  • Do something if nonNull and something else if Null

    • Optional.ofNullable(obj).map(obj -> {
          doSomething(obj)
          return obj;
      }).orElseGet(() -> {
          logForNull();
          return null;
      });

      HereIf the object is nonNull, then only the value will be applied to the mapping function

Do you know - Series - 4: Boxing and Unboxing - Integer assignment and comparison

We know about boxing and unboxing in Java. It is about automatic conversion of primitive type value into its Wrapper Object equivalent type...