Today I came across a solution for this problem: https://leetcode.com/problems/group-anagrams/submissions/
The author used AbstractList to solve this problem. And the solution looks somewhat like this
import java.util.AbstractList;
class Solution {
private List<List<String>> result;
private HashMap<String, List<String>> map = new HashMap<>();
public List<List<String>> groupAnagrams(String[] strs) {
return new AbstractList<>() {
public List<String> get(int key) {
if (result == null)
init(strs);
return result.get(key);
}
public int size() {
if (result == null)
init(strs);
return result.size();
}
};
}
private void init(String[] strs) {
for (String str : strs) {
char[] ch_map = str.toCharArray();
Arrays.sort(ch_map);
String key = String.valueOf(ch_map);
if (!map.containsKey(key))
map.put(key, new ArrayList<>());
map.get(key).add(str);
}
result = new ArrayList<>(map.values());
}
}
The produced test result is 0ms ~ 1ms.
If I removed
if (result == null)
init(strs);
from get(int key) and int size(). Then I put the init(strs) to the start of the function like this:
...
public List<List<String>> groupAnagrams(String[] strs) {
init(strs);
return new AbstractList<>() {
public List<String> get(int key) {
return result.get(key);
}
public int size() {
return result.size();
}
};
}
...
The test result for this case is 10ms ~ 15ms.
I tried to print the number of time init(strs) is called, but it returned 1 time for both cases.
My question is why it is significantly faster when you put the init(strs) inside the AbstractClass ?