Note that it was unexpectedly difficult to invert the list in Java.
[1, 2, 3].reverse
In ruby, the array is easily inverted as shown in ↑. I thought that Java would also have inversion as standard, such as Stream API,
list.stream().reverse();
I couldn't do this. I searched for various streams, but I couldn't find it, so I was in trouble.
For the time being, the folly of turning the list from the opposite side with a for statement to generate an inverted list. .. ..
So, I tried to summarize ** 3 ways to invert the list **.
This is the most standard method provided by the standard library.
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
Collections.reverse(list);
// list = [f, e, d, c, b, a]
Note that this process changes list
destructively.
By the way, Collections
is a collection of processes for manipulating collections such as List
and Set
. For example, shuffle
and sort
.
If you frequently traverse the structure to the right and left, it's a good idea to turn it into a bidirectional list.
Deque<String> deque = new LinkedList<>(list);
//order
for(String s: deque) {
//Processing of s
}
//Reverse
Iterator<String> iter = deque.descendingIterator();
while(iter.hasNext()) {
String s = iter.next();
//Processing of s
}
However, the drawback is that it becomes a little legacy writing. .. ..
You can also use the Stream API. Stream processing itself is basically independent of the order of elements, and is good at processing independently for each element. On the other hand, we are not good at processing that involves order relations. However, the order can be guaranteed and can be used to invert.
//A little long. .. .. However, if the process of obtaining the reverse order list does not appear many times
List<String> reversedList = list.stream().collect(ArrayList::new, (l, e) -> l.add(0, e), (l, subl) -> l.addAll(0, subl));
collect is a method that describes the aggregation process.
(l, e)-> l.add (0, e)
is the body of the aggregation process. Now add an element to the beginning of list l.(l, subl)-> l.addAll (0, subl)
is a summary process during parallel execution. Summarize in the first argument. (At the time of parallel processing, the list is appropriately divided and processed, and the aggregated result is output for each. It is necessary to integrate these multiple results.)This is a simple thing to do, but it is troublesome to write. ** I really want to write as follows. ** **
List<String> reversedList = strs.stream().collect(MyCollectors.reverse());
In this case, prepare the following Collection implementation class.
MyCollectors.java
public class MyCollectors {
public static <T> Collector<T, List<T>, List<T>> reverse() {
return new Collector<T, List<T>, List<T>>() {
@Override
public Supplier<List<T>> supplier() {
return ArrayList::new;
}
@Override
public BiConsumer<List<T>, T> accumulator() {
return (l, e) -> l.add(0, e);
}
@Override
public BinaryOperator<List<T>> combiner() {
return (l, subl) -> {
l.addAll(0, subl);
return l;
};
}
@Override
public Function<List<T>, List<T>> finisher() {
//No final aggregation process is required, so the list is returned as is
return l -> l;
}
@Override
public Set<Characteristics> characteristics() {
//Parallel processing possible
return EnumSet.of(Characteristics.CONCURRENT);
}
};
}
}
It's a hassle to write, but once you write it, you can easily use it with stream processing.
If the inverted list itself is an intermediate product, there is no need to invert the list. For example, if you want to combine strings in reverse order, you don't need to create an inverted list, just do the following:
List<String> strs = Arrays.asList("a", "b", "c", "d", "e", "f");
String reverse = strs.stream().reduce((e1, e2) -> e2.concat(e1)).get();
// reverse = "fedcba"
In the case of Java, the chain method cannot be easily done with just one word, but there are three main methods. 0. Use Java standard Collections.reverse
Recommended Posts