我需要在我的文件系统中找到第一个免费索引,其中包含名称流作为源。
考虑清单:[" New2"," New4"," New0"," New1",...] 第一个未使用的索引将是3。
int index = 0;
try (IntStream indexes = names.stream()
.filter(name -> name.startsWith("New"))
.mapToInt(Integer::parseInt)
.distinct()
.sorted())
{
// I was thinking about making possible indexes stream, removing existig ones from try-with-resource block, and getting .min().
IntStream.rangeClosed(0, 10)... // Idk what to do.
}
我要求别人帮我找到合适的语法或提出更好的解决方案。
答案 0 :(得分:7)
最有效的方法是收集到BitSet
:
int first = names.stream()
.filter(name -> name.startsWith("New"))
.mapToInt(s -> Integer.parseInt(s.substring(3)))
.collect(BitSet::new, BitSet::set, BitSet::or).nextClearBit(0);
请注意,这些位本质上是分类和不同的。此外,总会有一个“免费”索引。如果0
和最大数字之间没有间隙,则下一个空格将是最大值+ 1,如果根本没有匹配元素,则下一个空格将为零。
答案 1 :(得分:4)
你可以:
例如:
List<String> names = Arrays.asList("New2", "New4", "New0", "New1");
Set<Integer> taken = names.stream()
.map(s -> s.replaceAll("\\D+", ""))
.map(Integer::parseInt)
.collect(Collectors.toSet());
int first = IntStream.range(0, names.size())
.filter(index -> !taken.contains(index))
.findFirst()
.orElse(names.size());
答案 2 :(得分:0)
为了好玩,如果您知道,您最多有63个参赛作品......
private static int firstMissing(List<Long> input) {
if (!input.contains(0L)) {
return 0;
}
long firstMissing = Long.lowestOneBit(~input.stream().reduce(1L, (i, j) -> i | 1L << j));
int result = 0;
while (firstMissing != 0) {
++result;
firstMissing = firstMissing >> 1;
}
return result - 1;
}
这就是@Holger所做的(来自我的+1),但没有使用BitSet的额外惩罚。