Fundamentals 11 min read

Top 10 Java Mistakes Every Developer Should Avoid

This article lists the ten most common errors Java developers make, explains why each is problematic, and provides clear code examples and best‑practice alternatives to help you write safer, more efficient Java code.

Programmer DD
Programmer DD
Programmer DD
Top 10 Java Mistakes Every Developer Should Avoid

Array to ArrayList

When converting an array to an ArrayList, developers often write List<String> list = Arrays.asList(arr);. This returns a fixed‑size list implemented by a private static class inside java.util.Arrays, which does not support add. To obtain a true java.util.ArrayList, create it with new ArrayList<>(Arrays.asList(arr)).

List<String> list = Arrays.asList(arr);
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

Check if an Array Contains a Value

Developers sometimes convert the array to a Set and call contains, which adds unnecessary overhead. A simpler approach is to use Arrays.asList(arr).contains(targetValue) or a manual loop.

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
Arrays.asList(arr).contains(targetValue);
for (String s : arr) {
    if (s.equals(targetValue))
        return true;
}
return false;

Removing an Element from a List Inside a Loop

Iterating with an index and calling list.remove(i) shrinks the list, causing the next index to skip elements. Using a foreach loop to remove elements throws ConcurrentModificationException. The correct way is to use an Iterator and call iter.remove() after next().

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = 0; i < list.size(); i++) {
    list.remove(i);
}
System.out.println(list); // prints [b, d]
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
    String s = iter.next();
    if (s.equals("a")) {
        iter.remove();
    }
}

Hashtable vs. HashMap

From an algorithmic perspective, Hashtable is just a name for a hash‑based data structure. In Java, the modern equivalent is HashMap. The key difference is that Hashtable is synchronized, so most code prefers the unsynchronized HashMap for better performance.

Using Raw Types in Collections

Raw types bypass generic type checking and can cause ClassCastException. The example shows adding an Integer to a List<String> via a raw‑type method, which crashes when the element is retrieved.

public static void add(List list, Object o) {
    list.add(o);
}
public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    add(list, 10);
    String s = list.get(0);
}

Running this code throws

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

.

Access Modifiers

Exposing fields as public makes them directly mutable from outside the class, which is a poor design. It is generally better to use the most restrictive access level that still allows the required functionality.

ArrayList vs. LinkedList

Both classes implement List, but they have different performance characteristics. ArrayList provides fast random access, while LinkedList excels at frequent insertions and deletions when random access is rare.

Mutable vs. Immutable Objects

Immutable objects are simple and safe but can generate many temporary objects, increasing garbage‑collection pressure. Mutable objects (e.g., StringBuilder) are preferable when building large strings or aggregating results.

String result = "";
for (String s : arr) {
    result = result + s;
}

Superclass and Subclass Constructors

If a superclass does not define a no‑argument constructor, the compiler will not insert one automatically. Subclass constructors implicitly call super(), so the absence of a default constructor causes a compilation error. Adding an explicit no‑arg constructor to the superclass or explicitly invoking an existing superclass constructor resolves the issue.

String Literals vs. Constructor

Creating a string with double quotes uses the string pool, so identical literals refer to the same object ( a == b is true). Using new String() always creates a new object, so c == d is false, although equals remains true.

String a = "abcd";
String b = "abcd";
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d); // false
System.out.println(c.equals(d)); // true

Future Work

The list is based on analysis of many open‑source projects, Stack Overflow questions, and popular Google searches. It is not an official ranking, but the items are indeed common pitfalls. Readers are encouraged to comment with additional mistakes they have encountered.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaHashMapCollectionsArrayListImmutableMutablecommon mistakes
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.