Java - Common Points of Confusion
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 injava.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 withint[] 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.