Perhaps you assume that they have to be more complex than they are.
They are designed to be super simple pieces of code which don't do very much in themselves, but as pieces of code you can pass to a library which can use these pieces of code.
This example prints 100 UUIDs using a Supplier and a Consumer
Stream.generate(UUID::random) // <<< Supplier<UUID>
.limit(100)
.forEach(System.out::println); // <<< Consumer<UUID>
A longer example is
Supplier<UUID> uuidSupplier = UUID::random;
Consumer<UUID> uuidConsumer = System.out::println;
Stream.generate(uuidSupplier)
.limit(100)
.forEach(uuidConsumer);