简体   繁体   中英

Java 8 parallel stream or method execution

I have a class that constructs several foo objects. The problem right now is that the class iterates one by one down a list and builds them. I want to see if there's a way to make all of the building happen in parallel. Here's the class in question:

public List<Foo> create() {}
    List<Class> fooTypes = Arrays.asList(
                    Foo1.class,
                    Foo2.class,
                    Foo3.class,
                    Foo4.class,
                    Foo5.class,
                    Foo6.class
            );

    List<Foo> foos = new ArrayList<>();

    for(Class<? extends Foo> fooType : fooTypes) {
        Optional<Foo> foo = findByType(fooType);
        if(foo.isPresent()) {
            foos.add(foo.get());
        }
    }
    return foos;
}

private Optional<Foo> findByType(Class<? extends Foo> fooClass) {
    if(fooClass.isAssignableFrom(Foo1.class)) {
        return Optional.ofNullable(foo1());
    }
    if(fooClass.isAssignableFrom(Foo2.class)) {
        return Optional.ofNullable(foo2());
    }
    if(fooClass.isAssignableFrom(Foo3.class)) {
        return Optional.ofNullable(foo3());
    }
    if(fooClass.isAssignableFrom(Foo4.class)) {
        return Optional.ofNullable(foo4());
    }
    if(fooClass.isAssignableFrom(Foo5.class)) {
        return Optional.ofNullable(foo5());
    }
    if(fooClass.isAssignableFrom(Foo6.class)) {
        return Optional.ofNullable(foo6());
    }
    return Optional.empty();
}

private Alert foo1() {
    return new Foo1Builder().build();
}
private Alert foo2() {
    return new Foo2Builder().build();
}
private Alert foo3() {
    return new Foo3Builder().build();
}
private Alert foo4() {
    return new Foo4Builder().build();
}
private Alert foo5() {
    return new Foo5Builder().build();
}
private Alert foo6() {
    return new Foo6Builder().build();
}

Is there a way to convert the foreach loop into a java 8 parallel stream? If not, is going the executor route outlined here the correct way to go? I tried something like this to implement parallel streams but something is just not correct:

foos = fooTypes
        .parallelStream()
        .filter(a -> findByType(a).isPresent())
        .map(Optional::get)
        .collect(Collectors.toList());

A parallel stream will be much less efficient than a sequential stream for such a small number of elements. It's overkill.

But you can use a Stream, indeed:

foos = fooTypes
        .stream()
        .map(this::findByType)
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());

That said, I really don't know what you gain by iterating on the classes to find which method to call on each class. Why not just use

return Arrays.asList(new Foo1Builder().build(),
                     new Foo2Builder().build(),
                     ...);

It seems much less convoluted to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM