我有一个int列表,例如(1,2,4,6,7,8)。 我想知道Java 8中是否存在创建列表列表。
如果
(x,y)->x+1=y
它应该在同一个列表中。
在此示例中,输出应为:
(1,2), (4), (6,7,8)
我可以这样写:
public static List<List<int>> group(List<int> list, GroupFunctionByOrder groupFunction) {
List<List<int>> result = new ArrayList<>();
for (int l : list) {
boolean groupFound = false;
for (List<int> group : result) {
if (groupFunction.sameGroup(l, group.get(group.size()-1))) {
group.add(l);
groupFound = true;
break;
}
}
if (! groupFound) {
List<int> newGroup = new ArrayList<>();
newGroup.add(l);
result.add(newGroup);
}
}
return result;
}
public class GroupFunctionByOrder {
public boolean sameGroup(int l1, int l2){
return l1+1 == l2;
}
}
答案 0 :(得分:5)
您可以使用StreamEx库执行此操作:
List<List<Integer>> grouped = StreamEx.of(1,2,4,6,7,8)
.groupRuns((x, y) -> x + 1 == y)
.toList();
答案 1 :(得分:1)
不,这可能是不可能的。
由于流的非常本质 - 您无法深入了解下一步处理的值,也无法从流中的任意点提取值 - 做这样的事情是从Java流的角度来看是不可行的。
首先,您无法在流上下文中访问BiFunction
或BiPredicate
。如果可以的话,那么你就有机会根据先前的顺序将值分开。
答案 2 :(得分:1)
java7中有效的方法也可以在java8中运行:)
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,4,6,7,8);
List<List<Integer>> result = new ArrayList<>();
List<Integer> prev = new ArrayList<>();
prev.add(list.get(0));
//iterate over the list
for (int i = 1 ; i < list.size(); i++){
// Add to list if does not satisfy condition
if (list.get(i) != list.get(i-1) +1){
result.add(prev);
prev = new ArrayList();
}
prev.add(list.get(i));
}
result.add(prev);
// print result
for(List<Integer> p : result) {
Object[] arr = p.toArray();
System.out.print(Arrays.deepToString(arr));
}
}
}
答案 3 :(得分:0)
我不知道Java 8中的直接方式,但这是另一种解决方案:
List<Integer> list = List.of(1, 2, 4, 6, 7, 8);
List<List<Integer>> result = new ArrayList<>();
int start = 0, i = 1, size = list.size();
while (i < size) {
while (i < size && list.get(i - 1) + 1 == list.get(i)) i++;
result.add(list.subList(start, i));
start = i++;
}
System.out.println(result); // [[1, 2], [4], [6, 7, 8]]
这使用List.subList
,它返回原始列表支持的子列表视图。这段代码的想法是移动索引直到条件被破坏,将子列表添加到结果中,然后从那一点开始。