JavaRush /Java Blog /Random EN /10 Mistakes Often Made by Java Developers
theGrass
Level 24
Саратов

10 Mistakes Often Made by Java Developers

Published in the Random EN group
10 mistakes often made by Java developers - 1
This list includes 10 mistakes that Java developers often 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 a class object ArrayListwhich is an internal private static class (private static class)of the class Arrays, and this 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));

    A class constructor java.util.ArrayListcan take as a parameter all objects that implement an 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 works, but there is no need to convert it 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 method 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]

    This turns out to be a serious mistake. When an element is removed, the size Listis reduced and the element indices change.

    So avoid this method if you want to remove multiple elements in a loop using an index.

    You may know that using an iterator is the correct 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 receive a ConcurrentModificationException .

    The correct thing to do is:

    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 loop-style for-each, the compiler will call the method remove(), and only then next(), which will raise an error ConcurrentModificationException. You can look at the code ArrayList.iterator().

  4. Hashtableagainst HashMap.

    Due to the corresponding 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 it should not be used Hashtablewhere HashMap.

    HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap .

    10 basic questions about the Map interface

  5. Use collections without content restrictions

    In Java , collections without content restrictions are often confused with collections with a content type mask. 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 actually limit anything. Consider the following code, where Listit is used without restrictions 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 cannot be sure what is inside. And in order to understand the full depth of the difference between Set, Set<?>and Set<Object>- read this and this link.

  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 don’t know how it differs ArrayListfrom LinkedList, they use the first one due to its greater popularity. However, there is a huge difference in performance between them. In fact, the choice between them should be dictated by their internal features - ArrayListit allows you to quickly access an arbitrary array element, 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(Modifiable) vs. Immutable(Immutable)

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

    Basically, to avoid preparing intermediate objects, a mutable object is used. One of the classic examples is the concatenation of a large number of strings. If you use an immutable object of type String, then you create a lot of objects that will immediately go to the garbage collector. This wastes time and CPU energy, so the correct solution is to use mutable objects (for example 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 the same way, without creating unnecessary objects. When working with large objects, such as collections, passing a collection to a method for sorting and returning the result in another collection is a completely unnecessary waste of resources. ( Answer from dasblinkenlight on Stack Overflow ).

    Why is a String class object immutable?

  9. Class constructors SuperandSub

    10 mistakes often made by Java developers - 2

    This compilation error is caused by the fact that the ancestor class does not have a default constructor defined. In Java , unless you specify a class constructor yourself, the compiler will create a default constructor that requires no arguments. If the constructor is described in the class Superas Super(String s){}, the compiler itself will not add anything. This is what we see in our example.

    The constructor of the class Sub, no matter which one, will call the default constructor of the class 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 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, read Create Java String Using "" or Constructor? .

Future plans. This list is based on my analysis of a huge number of Open Source projects from GitHub, questions from Stack Overflow, and popular queries on Google. I don’t presume to prove that they are really among the ten most serious mistakes, but they are actually very common.
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION