When implementing processing with Java List, you may say "I want to process 100 lists at a time". Isn't it time to bulk insert in DB? Without it, I would be crazy. It is a memo that you should not forget because it seems that you will make the same mistake by implementing so-called Bulk-like processing with the one implemented in Java.
There was a post that I referred to before, and I mostly use it, but even if I looked it up, it didn't come out easily. .. I didn't like it. ,. ,. ,. , If you say "I've seen this code" or "I mean this post", I'd appreciate it if you could let me know.
public interface BulkHelper<T> extends Iterable<T> {
/**
*Iterate a List of the size set by the first argument.
* @param size The size of the list to be processed in a batch
* @param list List to process
*/
default void doMethod(int size, Consumer<? super List<T>> list) {
final List<T> _list = new ArrayList<T>(size);
for (T t : this) {
if(_list.size() == size) {
list.accept(_list);
_list.clear();
}
_list.add(t);
}
if(_list.size() > 0) list.accept(_list);
}
/**
*Set the list to iterate.
*This method is mandatory to call.
* @param itr
* @return
*/
public static <T> BulkHelper<T> setList(Iterable<T> itr){
return () -> itr.iterator();
}
}
** When using **
public static void main(String[] args) {
List<String> list = Arrays.asList("AAA", "BBB", "CCC", "DDD", "EEE", "FFF","GGG");
BulkHelper.setList(list).doMethod(2, _list -> {
System.out.println(_list);
});
}
result
[AAA, BBB]
[CCC, DDD]
[EEE, FFF]
[GGG]
I did this when I wanted to repack the batch processing into a List and process it in parallel.
public static void main(String[] args) {
List<String> list = Arrays.asList("AAA", "BBB", "CCC", "DDD", "EEE", "FFF","GGG");
List<List<String>> copyList = new ArrayList<>();
BulkHelper.setList(list).doMethod(2, _list -> {
copyList.add(_list);
});
copyList.parallelStream().forEach(System.out::println);
}
result
[[GGG], [GGG], [GGG], [GGG]]
No. ,
The processing here in the BulkHelper interface.
if(_list.size() == size) {
list.accept(_list);
_list.clear();
}
_list.add(t);
The reference destination is always _list, and because clear () and add () are repeated, all the elements have referred to the [GGG] that was last processed in the List. It's just a mistake.
BulkHelper.setList(list).doMethod(2, _list -> {
ArrayList<String> clone = new ArrayList<>(_list);
copyList.add(clone);
});
Actually, I want to do something on the interface side, but what I suddenly came up with was to do something new inside the process.
Thanks to @Kilisame and @swordone's suggestions, we were able to solve the interface neatly as follows! Thank you!
public interface BulkHelper<T> extends Iterable<T> {
/**
*The List of the first argument is processed for each size of the second argument.
* @param list List to process
* @param size Bulk processing size
* @param bulkList Processing content
*/
public static <T> void extract(List<T> list, int size, Consumer<? super List<T>> bulkList) {
for (int i = 0; i < list.size(); i += size) {
List<T> _list = new ArrayList<>(list.subList(i, Integer.min(i + size, list.size())));
bulkList.accept(_list);
}
}
}
** When using **
public static void main(String[] args) {
List<String> list = Arrays.asList("AAA", "BBB", "CCC", "DDD", "EEE", "FFF","GGG");
List<List<String>> copyList = new ArrayList<>();
BulkHelper.extract(list, 2, _list -> {
copyList.add(_list);
});
copyList.parallelStream().forEach(System.out::println);
}
It's refreshing ~: star2:
Recommended Posts