I thought of making this post when I found myself confused by some very common methods we use in Java.

length vs length() vs size()

  • size() is a method defined in java.util.Collection, so it is available for any collection in Java, and returns to the number of elements in the collection. You cannot use this with strings.
  • length is a field on an array object. If you initialize the array with int[] a = new int[4], a.length always returns 4 (the capacity of the array)
  • length() is exclusively for strings. String, StringBuilder etc - to know the length of the String.

To summarize, use length only on arrays (int[], double[], String[]) to know the length of the arrays.

String is not a vanilla array, so you can’t use length and it’s not even a Collection (so you can’t use size(). This is the only case where you’d use length().

int vs Integer

A lot of content online focuses on what these are. (int is a primitive type. Integer is a class) - but I think that’s sort of not very helpful when it comes to application. The way I understood is Integer is a wrapper around int which makes your life much easier with predefined methods. You might also find people using some jargon on the lines of boxing and autoboxing. It’s just a fancy way of saying:

// You can do this and java won't 
// shout back at ya
Integer n = 8;
// It would internally do
//  something like this
Integer n = new Integer(8);
// or this
Integer n = Integer.valueOf(8);

Verdict

Use int. However, if the value can be null or is to be used as an Object or Collections - use Integer. Using int also gives you performance benefits that come with primitive types.

HashMap vs Hashtable

Hashtable is usually considered legacy (“old”) code. There’s virtually nothing about Hashtable that can’t be done using HashMap or derivations of HashMap. However, there are some differences:

Hashtable is synchronized, whereas HashMap is not. This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones. However, you’re still better off using Collections.synchronizedMap() or ConcurrentHashMap - read more in the StackOverflow answer below

This is taken from this answer by Josh Brown here

public vs unspecified vs protected

I made an effort to show access modifiers with some actual code. Click on the image above to open it in a new tab.

StringBuilder vs StringBuffer

StringBuffer is synchronized, StringBuilder is not.

implements Runnable vs extends Thread

Use implements Runnable. Period.

Pass-By-Value / Pass-By-Reference

There are a ton of upvoted answers on this question on StackOverflow. And they are heavily upvoted. However, from a beginner standpoint, I find them highly misleading.

Give yourself 2 minutes of your time to understand the code below, and I assure you you’ll understand how Java really handles variable passing.

public class Main {
    
    public static void method1(List<List<Integer>> a, List<Integer> b, int c){
        a.add(Arrays.asList(1,2,3));
        b.add(7);
        c = 5;
        return;
    }
    
    public static void main(String[] args) {
        List<List<Integer>> x = new ArrayList<>();
        List<Integer> y = new ArrayList<>();
        y.add(4);
        y.add(5);
        y.add(6);
        int z = 1;
        method1(x, y, z);
        System.out.println(x + " " + y + " " + z); // prints [[1, 2, 3]] [4, 5, 6, 7] 1
    }
}

In short, collections/objects seem to be pass by reference, primitive types are pass by value.

add() vs offer() in PriorityQueue

The two functions come from two different interfaces that PriorityQueue implements:

add() comes from Collection. offer() comes from Queue.

  • For PriorityQueue, the two functions are synonymous.
  • For a capacity-constrained queue, the difference is that add() always returns true and throws an exception if it can’t add the element, whereas offer() is allowed to return false if it can’t add the element.

LinkedList vs Stack

Stack class is mostly a leftover that has become more or less redundant with the newer Java Collections Framework.

String .equals() vs ==

Consider the below example:

String s = "abcd"; 
System.out.println(s.substring(1,2)); //prints b
System.out.println(s == "abcd"); //prints false
System.out.println(s.substring(1,2) == "b"); //prints false
System.out.println(s.substring(1,2).equals("b")); //prints true

The above code should tell you why people are advised to use .equals() instead of ==. Because .substring() is invoked at runtime, hence it generates distinct objects.

Interfaces & Inner Class

  • Multiple inheritance - A class can only extend a single class, can implement multiple interfaces though.
  • Using Interfaces - Create an interface when you think about behaviours - A bird can walk and fly - IWalk and IFly can be interfaces.
  • Using Interface as Objects - You can define a method as -
public void rescueAnimal(IWalk animalThatWalks) {
    System.out.println("I just rescued an animal that walks");
}
  • Using Inner Classes - Use when existence of class B alone doesn’t make sense if class A doesn’t exist.
    • Bad Example, Flock and Bird (Bird can exist without a Flock)
    • Good Example, Planet AND Life (Life cannot exist without a Planet)
This blog post is part of the Advanced Java Series. Continue here with the Java Memory Model


Feeling generous ? Help me write more blogs like this :)


Feeling even more generous ?

$20 can feed a poor child for a whole year. Akshaya Patra (Aak-sh-ayah pa-tra) is the world’s largest NGO school meal program, providing hot, nutritious school lunches to over 1.8 million children in 19,257 schools, across India every day. Your 20$ makes all the difference.