-
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 classArrayList
that is an inner private static class(private static class)
of classArrays
, which is not a classjava.util.ArrayList.
The classjava.util.Arrays.ArrayList
contains methodsset()
,get()
,contains()
, but does not contain any methods for adding elements, its size is fixed . To create a real onejava.util.ArrayList
, do this:ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
The class constructor
java.util.ArrayList
can take as a parameter all objects that implement the interfaceCollection
, 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).
-
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
List
toSet
. Converting toSet
will 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.
-
Removing an element from
List
in a loopConsider 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
List
is 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-each
works 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
In a style loopnext()
must be called before theremove()
.for-each
, the compiler will call the methodremove()
, and then laternext()
, which will raise an errorConcurrentModificationException
. You can see the codeArrayList.iterator()
. -
Hashtable
againstHashMap
.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 betweenHashtable
andHashMap
is that it isHashtable
synchronized. So you should not useHashtable
it where it is more suitableHashMap
. -
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,
Set
this is a collection without restrictions on content, andSet<?>
- a collection that still has restrictions, but these restrictions do not really limit anything. Consider the following code, whereList
unlimited 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<?>
andSet<Object>
- read this and this links. -
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. ArrayList
againstLinkedList
When developers do not know how it differs
ArrayList
fromLinkedList
, 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 -ArrayList
it allows you to quickly access an arbitrary element of the array, andLinkedList
- quickly add / remove elements in the array. Read the article at the link ArrayList vs. LinkedList to understand the reasons for their different performance.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 (egStringBuilder
).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 ).
-
Class constructors
Super
andSub
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
Super
asSuper(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 constructorSuper
, since nothing else is specified. Since there is no default constructor in the classSuper
, this will lead to a compilation error.The first solution to this problem is to add a default constructor to the class
Super
public Super(){ System.out.println("Super"); }
The second option is to remove the constructor we just described from the class
Super
so that the compiler creates a default constructor.And the last option is to add a call
super(value)
to the class constructorsSub
so that the existing class constructor is called instead of the default constructorSuper
-
" " 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? .
GO TO FULL VERSION