diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java b/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java index 9f3dac1da..2e197cd8a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java @@ -262,6 +262,24 @@ public class Opt { return this; } + + /** + * 如果包裹里元素的值存在,就执行对应的操作集,并返回本身 + * 如果不存在,返回一个空的{@code Opt} + * + *

属于 {@link #ifPresent}的链式拓展 + *

属于 {@link #peek(Consumer)}的动态拓展 + * + * @param actions 值存在时执行的操作,动态参数,可传入数组,当数组为空数组时并不会抛出 {@code NPE} + * @return this + * @throws NullPointerException 如果值存在,并且传入的操作为 {@code null} + * @author VampireAchao + */ + @SafeVarargs + public final Opt peeks(Consumer... actions) throws NullPointerException { + return Stream.of(actions).reduce(this, Opt::peek, (opts, opt) -> null); + } + /** * 如果包裹里元素的值存在,就返回本身,如果不存在,则使用传入的操作执行后获得的 {@code Opt} * diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/OptTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/OptTest.java index 9c52e98fe..647b86882 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/OptTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/OptTest.java @@ -9,6 +9,8 @@ import org.junit.Ignore; import org.junit.Test; import java.util.NoSuchElementException; +import java.util.function.Consumer; +import java.util.stream.Stream; /** * {@link Opt}的单元测试 @@ -63,6 +65,38 @@ public class OptTest { Assert.assertEquals("hutool", name); } + @Test + public void peeksTest() { + User user = new User(); + // 相当于上面peek的动态参数调用,更加灵活,你可以像操作数组一样去动态设置中间的步骤,也可以使用这种方式去编写你的代码 + // 可以一行搞定 + Opt.ofNullable("hutool").peeks(user::setUsername, user::setNickname, System.out::println); + // 也可以在适当的地方换行使得代码的可读性提高 + Opt.of(user).peeks( + u -> Assert.assertEquals("hutool", u.getNickname()), + u -> Assert.assertEquals("hutool", u.getUsername()) + ); + Assert.assertEquals("hutool", user.getNickname()); + Assert.assertEquals("hutool", user.getUsername()); + + // 注意,传入的lambda中,对包裹内的元素执行赋值操作并不会影响到原来的元素,这是java语言的特性。。。 + // 这也是为什么我们需要getter和setter而不直接给bean中的属性赋值中的其中一个原因 + String name = Opt.ofNullable("hutool").peeks(username -> username = "123", username -> username = "456", n -> Assert.assertEquals("hutool", n)).get(); + Assert.assertEquals("hutool", name); + + // 在控制台打印n次hutool + int n = 10; + @SuppressWarnings("unchecked") + Consumer[] actions = Stream.>generate(() -> System.out::println).limit(n).toArray(Consumer[]::new); + Opt.ofNullable("hutool").peeks(actions); + + // 当然,以下情况不会抛出NPE,但也没什么意义 + Opt.ofNullable("hutool").peeks().peeks().peeks(); + Opt.ofNullable(null).peeks(i -> { + }); + + } + @Test public void orTest() { // 这是jdk9 Optional中的新函数,直接照搬了过来