Uses for Optional

前端 未结 14 1701
眼角桃花
眼角桃花 2020-11-22 01:01

Having been using Java 8 now for 6+ months or so, I\'m pretty happy with the new API changes. One area I\'m still not confident in is when to use Optional. I se

14条回答
  •  佛祖请我去吃肉
    2020-11-22 01:22

    Here is an interesting usage (I believe) for... Tests.

    I intend to heavily test one of my projects and I therefore build assertions; only there are things I have to verify and others I don't.

    I therefore build things to assert and use an assert to verify them, like this:

    public final class NodeDescriptor
    {
        private final Optional label;
        private final List> children;
    
        private NodeDescriptor(final Builder builder)
        {
            label = Optional.fromNullable(builder.label);
            final ImmutableList.Builder> listBuilder
                = ImmutableList.builder();
            for (final Builder element: builder.children)
                listBuilder.add(element.build());
            children = listBuilder.build();
        }
    
        public static  Builder newBuilder()
        {
            return new Builder();
        }
    
        public void verify(@Nonnull final Node node)
        {
            final NodeAssert nodeAssert = new NodeAssert(node);
            nodeAssert.hasLabel(label);
        }
    
        public static final class Builder
        {
            private String label;
            private final List> children = Lists.newArrayList();
    
            private Builder()
            {
            }
    
            public Builder withLabel(@Nonnull final String label)
            {
                this.label = Preconditions.checkNotNull(label);
                return this;
            }
    
            public Builder withChildNode(@Nonnull final Builder child)
            {
                Preconditions.checkNotNull(child);
                children.add(child);
                return this;
            }
    
            public NodeDescriptor build()
            {
                return new NodeDescriptor(this);
            }
        }
    }
    

    In the NodeAssert class, I do this:

    public final class NodeAssert
        extends AbstractAssert, Node>
    {
        NodeAssert(final Node actual)
        {
            super(Preconditions.checkNotNull(actual), NodeAssert.class);
        }
    
        private NodeAssert hasLabel(final String label)
        {
            final String thisLabel = actual.getLabel();
            assertThat(thisLabel).overridingErrorMessage(
                "node's label is null! I didn't expect it to be"
            ).isNotNull();
            assertThat(thisLabel).overridingErrorMessage(
                "node's label is not what was expected!\n"
                + "Expected: '%s'\nActual  : '%s'\n", label, thisLabel
            ).isEqualTo(label);
            return this;
        }
    
        NodeAssert hasLabel(@Nonnull final Optional label)
        {
            return label.isPresent() ? hasLabel(label.get()) : this;
        }
    }
    

    Which means the assert really only triggers if I want to check the label!

提交回复
热议问题