Coverage Summary for Class: OptionalValue (it.polimi.ingsw.Misc)
Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
OptionalValue |
100%
(1/1)
|
84,6%
(11/13)
|
61,1%
(11/18)
|
74,1%
(20/27)
|
1 package it.polimi.ingsw.Misc;
2
3 import java.io.Serializable;
4 import java.util.Objects;
5 import java.util.function.Consumer;
6 import java.util.function.Function;
7
8 /**
9 * This class takes inspiration from {@link java.util.Optional} but adds serialization support and foregoes some
10 * lesser used methods in some instances.
11 * While {@link java.util.Optional} was never meant to be used as a persistent value in memory, the layer of abstraction
12 * it provides over null values was valuable enough to warrant a rewrite into an object that could be Serialized and shared
13 * over the net.
14 *
15 * @param <T> the internal type of the OptionalValue
16 */
17 public class OptionalValue<T> implements Serializable {
18 private final T value;
19
20 /**
21 * Private constructor for the object
22 */
23 private OptionalValue() {
24 this.value = null;
25 }
26
27 /**
28 * Private constructor for the object
29 */
30 private OptionalValue(T value) {
31 this.value = value;
32 }
33
34 /**
35 * Creates a new wrapping around a non null value
36 *
37 * @param element non null element to wrap an optional value around
38 * @param <T> the type of element stored inside the Optional
39 * @return the {@link OptionalValue} containing element
40 */
41 public static <T> OptionalValue<T> of(T element) {
42 Objects.requireNonNull(element);
43 return new OptionalValue<>(element);
44 }
45
46 /**
47 * Creates a new wrapping around a value
48 *
49 * @param element possibly null value to wrap this object around
50 * @param <T> The type of value stored inside the optional value
51 * @return an empty {@link OptionalValue} if element is null, otherwise an {@link OptionalValue} wrapping element
52 */
53 public static <T> OptionalValue<T> ofNullable(T element) {
54 if (element == null) {
55 return new OptionalValue<>();
56 }
57 return new OptionalValue<>(element);
58 }
59
60 /**
61 * Check if no value is present inside the optional
62 *
63 * @return true if the internal value is absent
64 */
65 public boolean isEmpty() {
66 return value == null;
67 }
68
69 /**
70 * Check if a value is present inside the optional
71 *
72 * @return true if the internal value is present
73 */
74 public boolean isPresent() {
75 return value != null;
76 }
77
78 /**
79 * Retrieve the inner value
80 *
81 * @return the inner value of the optional, if present
82 * @throws NullPointerException if no inner value is present
83 */
84 public T get() {
85 if (value == null) {
86 throw new NullPointerException();
87 }
88 return value;
89 }
90
91 /**
92 * Retrieve the inner value
93 *
94 * @param otherwise the default value to return if no inner value is present
95 * @return the inner value of the optional, if present. Otherwise returns the input value
96 */
97 public T orElse(T otherwise) {
98 if (value == null) {
99 return otherwise;
100 }
101 return value;
102 }
103
104 /**
105 * If a value is present, run the provided consumer over it
106 *
107 * @param consumer a function to run over the contained value (if present)
108 */
109 public void ifPresent(Consumer<? super T> consumer) {
110 if (value == null) {
111 return;
112 }
113 consumer.accept(value);
114 }
115
116 /**
117 * If a value is present, returns the result of applying the given Optional-bearing mapping function to the value, otherwise returns an empty OptionalValue.
118 *
119 * @param mapper the mapping function to apply to a value, if present
120 * @param <U> The type of value of the Optional returned by the mapping function
121 * @return the result of applying an Optional-bearing mapping function to the value of this Optional, if a value is present, otherwise an empty Optional
122 */
123 public <U> OptionalValue<U> flatMap(Function<? super T, OptionalValue<U>> mapper) {
124 if (value == null) {
125 return OptionalValue.empty();
126 }
127 return mapper.apply(value);
128 }
129
130 /**
131 * Get an empty value instance
132 *
133 * @param <T> The type of value stored inside the optional value
134 * @return an empty {@link OptionalValue}
135 */
136 public static <T> OptionalValue<T> empty() {
137 return new OptionalValue<>();
138 }
139
140 /**
141 * Returns the hash code of the value, if present, otherwise 0 (zero) if no value is present.
142 *
143 * @return hash code value of the present value or 0 if no value is present
144 */
145 @Override
146 public int hashCode() {
147 return Objects.hash(value);
148 }
149
150 /**
151 * Indicates whether some other object is "equal to" this OptionalValue. The other object is considered equal if:
152 * <ul>
153 * <il>it is also an Optional and;</il>
154 * <il>both instances have no value present or;</il>
155 * <il>the present values are "equal to" each other via equals().</il>
156 * </ul>
157 *
158 * @param o the object to be tested for equality
159 * @return true if the two objects are considered equal
160 */
161 @Override
162 public boolean equals(Object o) {
163 if (this == o) return true;
164 if (!(o instanceof OptionalValue<?> optional)) return false;
165 return Objects.equals(value, optional.value);
166 }
167 }