有对象列表:
[Object1, Object2, Object3, Object4, Object5]
应拆分为以下结构:
[
[Object1, Object2, Object3]
[Object3, Object4, Object5]
]
此代码可以拆分,而子列表的最后一个元素不重叠:
Streams.stream(Iterables.partition(maps,3)).collect(Collectors.toList());
结果是:
[Object1, Object2, Object3]
[Object4, Object5]
Object3 在这里缺失。
是否有一种优雅的方法来拆分此List
,并重复将上一个子列表的
最后一个元素作为下一个子列表的第一个元素?
我已经尝试过这种方法,但是看起来并不像我希望的那么优雅:
List<List<String>> res= new ArrayList<>();
for (int y = 0; y < input.size() - 1;) {
List<String> sub = paths.subList(y, y += 3);
res.add(sub)
--y;
}
答案 0 :(得分:4)
带有流的java-8解决方案,其中Intstream.iterate()
具有以下签名,仅带有2个参数:
IntStream iterate(int seed, IntUnaryOperator f)
如下:
List res = IntStream.iterate(0, i -> i + step - 1)
.limit(input.size() / (step - 1))
.mapToObj(i -> input.subList(i, Math.min(i + step, input.size())))
.collect(Collectors.toList());
step
大小为3,输出:
[[a, b, c]] //List<String> input = Arrays.asList("a","b","c");
[[a, b, c], [c, d]] //List<String> input = Arrays.asList("a","b","c","d");
答案 1 :(得分:3)
就我个人而言,我将使用当前循环的一种变体,但将增量移至循环头。另请注意,您的代码仅在列表完全可分割时才有效,因此在我的版本中为Math.min
。
public static <T> List<List<T>> split(List<T> input, int k) {
List<List<T>> res= new ArrayList<>();
for (int i = 0; i < input.size() - 1; i += k-1) {
res.add(input.subList(i, Math.min(input.size(), i + k)));
}
return res;
}
或者,如果您更喜欢Streams,则可以使用IntStream.iterate
1 :
public static <T> List<List<T>> split(List<T> input, int k) {
return IntStream.iterate(0, i -> i < input.size(), i -> i + k-1)
.mapToObj(i -> input.subList(i, Math.min(input.size(), i + k)))
.collect(Collectors.toList());
}
示例,对于两个版本:
List<Integer> input = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println(split(input, 3));
// [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]]
1)注意:Java 9+中提供了三参数版本。有关Java 8,请参见Pankaj's answer。
答案 2 :(得分:0)
有很多方法可以做到这一点,其中一种是优雅的方法。
public class SplitList {
public static <T> List<List<T>> split(List<T> list) {
if (list == null || list.isEmpty()) {
throw new RuntimeException("List shouldn't be empty");
}
int[] positions = {0, (list.size() + 1) / 2, list.size()};
boolean isListOdd = list.size() % 2 != 0;
return IntStream.rangeClosed(0, 1)
.mapToObj(i -> list.subList(positions[i] + (isListOdd ? (i != 0 ? -1 : 0) : 0), positions[i + 1]))
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> list = Arrays.asList("A", "B", "C", "D", "E");
System.out.println(split(list));
}
}
这是输出
[[A, B, C], [C, D, E]]