“寻找第一个自由”;索引“;使用java流
我需要在我的文件系统中找到第一个以名称流为源的自由索引 考虑列表:[“New2”、“New4”、“New0”、“New1”、…] 第一个未使用的索引为3“寻找第一个自由”;索引“;使用java流,java,java-8,java-stream,Java,Java 8,Java Stream,我需要在我的文件系统中找到第一个以名称流为源的自由索引 考虑列表:[“New2”、“New4”、“New0”、“New1”、…] 第一个未使用的索引为3 int index = 0; try (IntStream indexes = names.stream() .filter(name -> name.startsWith("New")) .mapToInt(Integer::parseInt) .distinct() .sorted()) { /
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.
}
我请求某人帮助我找到适合我想法的语法或提出更好的解决方案。您可以:
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());
List name=Arrays.asList(“New2”、“New4”、“New0”、“New1”);
Set take=names.stream()
.map(s->s.replaceAll(\\D+,“”)
.map(整数::parseInt)
.collect(收集器.toSet());
int first=IntStream.range(0,names.size())
.filter(索引->!take.contains(索引))
.findFirst()
.orElse(names.size());
最有效的方法是收集到位集中
:
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,如果根本没有匹配元素,下一个自由值将是零。有趣的是,如果你知道你最多有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;
}
private static int firstMissing(列表输入){
如果(!input.contains(0L)){
返回0;
}
long firstMissing=long.lowstonebit(~input.stream().reduce(1L,(i,j)->i | 1L>1;
}
返回结果-1;
}
这就是@Holger所做的(+1),但是没有使用位集的额外惩罚。
Integer::parseInt
将失败,除非您首先删除前缀。为什么不使用collect(toSet())
?或者,您可以收集到一个列表,并将索引与值进行比较(.filter(i->take.get(i)>i)
)。谢谢@shmosel,收集到一套更好,更新。那确实很酷!+1(复选标记应该归你)我喜欢一行!谢谢!