Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding 1st free "index" using java streams

I need to find 1st free index in my file system having stream of names as source.

Consider list: ["New2", "New4", "New0", "New1", ...] 1st unused index of those will be 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.
}

I am asking someone to help me find right syntax for my idea or propose better solution.

like image 442
Ernio Avatar asked Dec 18 '22 11:12

Ernio


1 Answers

The most efficient way is to collect into a 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);

Note that the bits are intrinsically sorted and distinct. Also, there will always be a “free” index. If there is no gap between 0 and the maximum number, the next free will be maximum+1, if there are no matching elements at all, the next free will be zero.


Starting with Java 9, we can do even more efficient with

int first = names.stream()
    .filter(name -> name.startsWith("New"))
    .mapToInt(s -> Integer.parseInt(s, 3, s.length(), 10))
    .collect(BitSet::new, BitSet::set, BitSet::or).nextClearBit(0);

which parses the relevant part of the string directly, saving the substring operation.

like image 60
Holger Avatar answered Jan 03 '23 03:01

Holger