0

If I have a list of timestamps and a file path of an object that I want to convert, can I make a collection of converters that expect the method signature Converter(filePath, start, end)?

More Detail (Pseuo-Code):

Some list that has timestamps (Imagine they're in seconds) path = somewhere, list = {0, 15, 15, 30},

How can I do something like this: list.stream.magic.map(start, end -> new Converter (path, start, end))?

Result: new Converter (path, 0, 15), new Converter(path, 15, 30)

Note: I'm aware of BiFunction, but to my knowledge, streams do not implement it.

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
Sarah Szabo
  • 10,345
  • 9
  • 37
  • 60
  • Please, clarify by an example, what you need to have in places of start and end? Do you mean all odd elements in the list should be binded to "start" arg, and all even - to the "end" arg; or something else? – diziaq May 19 '18 at 02:26
  • @diziaq Media Converters typically take start and end times, such as give me all the video from 25 seconds to 30 seconds. 25 is the start time, and 30 is the end time. – Sarah Szabo May 19 '18 at 02:35
  • I dont' see a 25 value in the list given in the question. So, please add to the post enumeration of (start, end) pairs you expect to obtain from that list. – diziaq May 19 '18 at 02:39
  • 1
    you mean to take two elements at a time in your list ? https://stackoverflow.com/questions/28622119/pick-2-elements-from-stream-at-a-time – Angel Koh May 19 '18 at 03:33
  • What is the type of that `Stream`? It doesn't sound like a valid application of streams at all. – daniu May 19 '18 at 11:30

1 Answers1

1

There are many approaches to get the required result using streams.

But first of all, you're not obliged to use Stream API, and in case of dealing with lists of tens and hundreds elements I would suggest to use plain old list iterations.

Just for instance try the code sample below.

We easily can see the two surface problems arising from the nature of streams and their incompatibility with the very idea of pairing its elements:

  • it's necessary to apply stateful function which is really tricky for using in map() and should be considered dirty coding; and the mapping produce some nulls on even places that should be filtered out properly;
  • problems are there when stream contains odd number of elements, and you never can predict if it does.

If you decide to use streams then to make it a clear way we need a custom implementation of Iterator, Spliterator or Collector - depends on demands. Anyway there are couple of non-obvious corner cases you won't be happy to implement by yourself, so can try tons of third-party stream libs. Two of the most popular are Streamex and RxJava. Definitely they have tools for pairing stream elements... but don't forget to check the performance for your case!

import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;

public class Sample
{
    public static void main(String... arg)
    {        
        String path = "somewhere";

        Stream<Converter> stream = Stream.of(0, 15, 25, 30).map(
            new Function<Integer, Converter>()
            {
                int previous;
                boolean even = true;

                @Override
                public Converter apply(Integer current)
                {
                    Converter converter = even ? null : new Converter(path, previous, current);

                    even = !even;

                    previous = current;

                    return converter;
                }
            }).filter(Objects::nonNull);

        stream.forEach(System.out::println);
    }

    static class Converter
    {
        private final String path;
        private final int start;
        private final int end;

        Converter(String path, int start, int end)
        {

            this.path = path;
            this.start = start;
            this.end = end;
        }

        public String toString()
        {
            return String.format("Converter[%s,%s,%s]", path, start, end);
        }
    }
}
diziaq
  • 6,881
  • 16
  • 54
  • 96
  • Collections containing odd numbers of timestamps aren't allowed and are field checked out of existence at the time the subroutine is called by throwing an `IllegalArgumentException` detailing why. – Sarah Szabo May 19 '18 at 21:20
  • Hmm, I wasn't aware that there was an obvious performance penalty between using Streams and iterators for operations. This isn't a performance heavy project any, so I'm fine. By the way, I didn't know about alternative Stream libraries, thanks for opening my eyes to them! – Sarah Szabo May 20 '18 at 05:22