Simple Java: the 10 most common errors made by Java developers. simplejava
This list summarizes the most common mistakes made by 10 Java developers.
Convert Array to ArrayList
When you need to convert an Array to an ArrayList, developers often do this:
List<String> list = Arrays.asList(arr);
Arrays. asList () returns an ArrayList, but note that this ArrayList is a static internal class of the Arrays class, not a java. util. ArrayList class. Java. util. arrays. the ArrayList class implements the set (), get (), and contains () methods, but does not implement the method for adding elements (in fact, you can call the add method, but there is no specific implementation, only throws the UnsupportedOperationException), so its size remains unchanged. To create a real java. util. ArrayList, you should do the following:
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
The ArrayList constructor can receive a Collection type, which is implemented by java. util. Arrays. ArrayList.
Determines whether an array contains a value.
Developers often do this:
Set<String> set = new HashSet<String>(Arrays.asList(arr));return set.contains(targetValue);
The above code works normally, but there is no need to convert it into a set Set. It takes additional time to convert a List to a set. In fact, we can simply use the following method:
Arrays.asList(arr).contains(targetValue);
Or
for(String s: arr){ if(s.equals(targetValue)) return true;}return false;
The first method is more readable.
Delete an element in the List in a loop.
Consider the following code to delete elements during iteration:
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);
Result printing:
[B, d]
There are a series of problems in the above method. When an element is deleted, the list size decreases, and the original index points to other elements. So if you want to delete multiple elements through indexes in a loop, it will not work correctly.
You may know that using the iterator is the correct way to delete elements in a loop, or you may know that the foreach loop is similar to the iterator, but this is not the case. 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);}
ConcurrentModificationException is thrown.
However, the following code is OK:
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 next () method must be called before the remove () method. In the foreach loop, the compiler will call the next method in the delete element operation mode, which causes ConcurrentModificationException. For more details, see the source code of ArrayList. iterator.
HashTable and HashMap
From an algorithm perspective, HashTable is a data structure name. However, in Java, this data structure is called HashMap. A major difference between HashTable and HashMap is that HashTable is synchronized. Therefore, you usually use HashMap instead of Hashtable.
More information: HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap Top 10 questions about Map
Raw type)
In Java, raw type and unbounded wildcard type are confusing. For example, Set is the original type, and Set <?> Is an unbounded wildcard type.
See the following code. The add method uses a List of the original type as the input 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);}
Running the above Code throws an exception:
Exception in thread "main" java. lang. ClassCastException: java. lang. Integer cannot be cast to java. lang. String
At...
It is very dangerous to use the original type set because it skips the generic type check and is insecure. In addition, Set, Set <?>, This is very different from Set <Object>. For details, see type erasure and Raw type vs. Unbounded wildcard.
Access Level
Developers often use public modifier fields. Although it is easy for others to directly obtain the value of this field through reference, this is a poor design. Based on experience, the access level of member attributes should be minimized.
Read more: public, default, protected, and private
ArrayList and rule list
Why do developers often use ArrayList and rule list, but do not know the difference between them, because they look very similar. However, there are huge performance differences between them. To put it simply, if there are a lot of operations that increase the number of delete operations and do not have a lot of random access elements, the primary list should be preferred.
Read more: ArrayList vs. Alibaba list
Variable and immutable
Immutable objects have many advantages, such as simplicity and security. However, a single object is required for each different value. Too many objects will cause a large amount of garbage collection. Therefore, a balance must be set between variable and immutable objects.
Generally, a variable object is used to avoid the generation of a large number of intermediate objects. A typical example is the concatenation of a large number of strings. If you use an immutable object, a large number of objects that meet the garbage collection standards will be generated immediately, which wastes a lot of time and effort on the CPU. Using mutable objects is the right solution (StringBuilder );
String result="";for(String s: arr){ result = result + s;}
In addition, variable objects are also required in some other cases. For example, you can input a variable object to a method and then collect multiple results without writing too many syntaxes. Another example is sorting and filtering: Of course, you can write a method to receive the original set and return a sorted set, but it is too wasteful for a large set.
Read more: Why String is Immutable ??
Why we need mutable classes?
Constructor of parent and child classes
This compilation error occurs because the default constructor of the parent class is not defined. In Java, if a class does not define a constructor, the compiler inserts a constructor without parameters by default. However, if a constructor is defined in the parent class, the compiler will not automatically insert a default non-argument constructor, which is exactly the case of the above demo;
For subclasses, neither the construction method without parameters nor the construction method with parameters will call the construction method without parameters of the parent class by default. When the compiler tries to insert super () into the two constructor classes () the compiler reports an error because the parent class does not have a default no-argument constructor;
To fix this error, it is simple:
1. Manually define a construction method without parameters in the parent class:
public Super(){ System.out.println("Super");}
2. Remove the custom constructor from the parent class.
3. Write the call of the constructor of the parent class in the subclass, for example, super (value );
"" Or constructor
There are two ways to create a string:
//1. use double quotesString x = "abc";//2. use constructorString y = new String("abc");
What are the differences between them?
The following code provides a quick answer:
String a = "abcd";String b = "abcd";System.out.println(a == b); // TrueSystem.out.println(a.equals(b)); // TrueString c = new String("abcd");String d = new String("abcd");System.out.println(c == d); // FalseSystem.out.println(c.equals(d)); // True