10 Common Mistakes Java Developers Make - 1
This list includes 10 common mistakes Java developers make.
  1. Converting an array to an ArrayList .

    To convert an array to an ArrayList , developers often use this method:

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

    Arrays.asList()will return an object of a class ArrayListthat is an inner private static class (private static class)of class Arrays, which is not a class java.util.ArrayList.The class java.util.Arrays.ArrayListcontains methods set(), get(), contains(), but does not contain any methods for adding elements, its size is fixed . To create a real one java.util.ArrayList, do this:

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

    The class constructor java.util.ArrayListcan take as a parameter all objects that implement the interface Collection, the implementation of which is inherited by the classjava.util.Arrays.ArrayList

    (private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable).

  2. Checking an array for a specific value.

    Developers often do this:

    Set<String> set = new HashSet<String>(Arrays.asList(arr));
    return set.contains(targetValue);

    The code is working, but there is no need to convert Listto Set. Converting to Setwill take additional time. In fact, everything is simple:

    Arrays.asList(arr).contains(targetValue);

    or

    for(String s: arr){
    	if(s.equals(targetValue))
    		return true;
    }
    return false;

    The first way is much shorter.

  3. Removing an element from Listin a loop

    Consider the following code that removes elements in a loop:

    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);

    Conclusion:

    [b, d]

    It turns out a serious error. When an element is removed, the size Listis reduced and the element indexes are changed.

    So don't use this method if you want to remove multiple elements in a loop using an index.

    You probably know that using an iterator is the right solution for removing elements in a loop, and you know that a style loop for-eachworks like an iterator, but it doesn't.

    Consider the following code:

    ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
    
    for (String s : list) {
    	if (s.equals("a"))
    		list.remove(s);
    }

    We will get a ConcurrentModificationException .

    Do it right like this:

    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();
    	}
    }

    The method next()must be called before the remove().

    In a style loop for-each, the compiler will call the method remove(), and then later next(), which will raise an error ConcurrentModificationException. You can see the code ArrayList.iterator().

  4. Hashtableagainst HashMap.

    Due to the respective implementation, Hashtable is the name of the data structure.

    But in Java, the name for a data structure is HashMap. One of the key differences between Hashtableand HashMapis that it is Hashtablesynchronized. So you should not use Hashtableit where it is more suitable HashMap.

    Hashmap vs. TreeMap vs. Hashtable vs. LinkedHashMap .

    Top 10 questions about the Map interface

  5. Using collections without content restrictions

    In Java, it's common to confuse collections with no restrictions on content, and collections with a mask on content type. For example, for sets, Setthis is a collection without restrictions on content, and Set<?>- a collection that still has restrictions, but these restrictions do not really limit anything. Consider the following code, where Listunlimited is used as a method parameter:

    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);
    }

    This code will throw an exception:

    Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    	at …

    Using collections without content restrictions is very dangerous because you can't be sure what's inside. And in order to understand the full depth of the difference between Set, Set<?>and Set<Object>- read this and this links.

  6. Access level

    Very often, developers use the access modifier for class fields public. This makes it easier to get the field value directly. It is more correct to use as limited access to class members as possible.

    public, default, protected, and private .

  7. ArrayListagainstLinkedList

    When developers do not know how it differs ArrayListfrom LinkedList, they use the former due to its greater popularity. However, there is a huge performance difference between the two. In fact, the choice between them should be dictated by their internal features - ArrayListit allows you to quickly access an arbitrary element of the array, and LinkedList- quickly add / remove elements in the array. Read the article at the link ArrayList vs. LinkedList to understand the reasons for their different performance.

  8. Mutable(Changable) vs. Immutable(Unchangeable)

    An immutable object has many advantages: simplicity, security, etc. But it requires a separate object for each new value, and too many objects come at a performance cost. There must be a balance when choosing between a mutable and an immutable object.

    Basically, a mutable object is used to avoid preparing intermediate objects. One of the classic examples is the concatenation of a large number of strings. If you are using an immutable object of type String, then you are creating a lot of objects that will immediately go to the garbage collector. This wastes CPU time and energy, so the correct solution is to use mutable objects (eg StringBuilder).

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

    Another example of using mutable objects is passing such an object to a method. This will allow you to return the result in it, without creating extra objects. When working with large objects, such as collections, passing a collection to a sort method and returning the result in another collection is completely overhead. ( Response from user dasblinkenlight on Stack Overflow ).

    Why is a String class object immutable?

  9. Class constructors SuperandSub

    10 Common Mistakes Java Developers Make - 2

    This compilation error is caused by the ancestor class not having a default constructor defined. In Java , if you don't declare a class constructor yourself, the compiler will generate a default constructor that takes no arguments. If the constructor is declared in the class Superas Super(String s){}, the compiler itself will not add anything. What we observe in our example.

    The class constructor Sub, no matter which one, will call the class's default constructor Super, since nothing else is specified. Since there is no default constructor in the class Super, this will lead to a compilation error.

    The first solution to this problem is to add a default constructor to the classSuper

    public Super(){
        System.out.println("Super");
    }

    The second option is to remove the constructor we just described from the class Superso that the compiler creates a default constructor.

    And the last option is to add a call super(value)to the class constructors Subso that the existing class constructor is called instead of the default constructorSuper

    Constructor of Super and Sub

  10. " " or constructor?

    There are two ways to create a string:

    //1. использовать двойные кавычки
    String x = "abc";

    //2. использовать конструктор
    String y = new String("abc");

    What is the difference between them?

    You can understand this from the following examples:

    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

    To learn more about how strings are stored in memory, see Create Java String Using "" or Constructor? .

Future plans. This list is based on my analysis of a huge number of open source github projects, Stack Overflow questions, and popular Google requests. I'm not going to prove that they really are among the ten most serious mistakes, but they are actually very common.