Aurimas Liutikas | 93554f2 | 2022-04-19 16:51:35 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. |
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
| 7 | * published by the Free Software Foundation. Oracle designates this |
| 8 | * particular file as subject to the "Classpath" exception as provided |
| 9 | * by Oracle in the LICENSE file that accompanied this code. |
| 10 | * |
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 14 | * version 2 for more details (a copy is included in the LICENSE file that |
| 15 | * accompanied this code). |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License version |
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 20 | * |
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| 22 | * or visit www.oracle.com if you need additional information or have any |
| 23 | * questions. |
| 24 | */ |
| 25 | package java.util; |
| 26 | |
| 27 | import java.util.function.LongConsumer; |
| 28 | import java.util.function.LongSupplier; |
| 29 | import java.util.function.Supplier; |
| 30 | |
| 31 | // Android-changed: removed ValueBased paragraph. |
| 32 | /** |
| 33 | * A container object which may or may not contain a {@code long} value. |
| 34 | * If a value is present, {@code isPresent()} will return {@code true} and |
| 35 | * {@code getAsLong()} will return the value. |
| 36 | * |
| 37 | * <p>Additional methods that depend on the presence or absence of a contained |
| 38 | * value are provided, such as {@link #orElse(long) orElse()} |
| 39 | * (return a default value if value not present) and |
| 40 | * {@link #ifPresent(java.util.function.LongConsumer) ifPresent()} (execute a block |
| 41 | * of code if the value is present). |
| 42 | * |
| 43 | * @since 1.8 |
| 44 | */ |
| 45 | public final class OptionalLong { |
| 46 | /** |
| 47 | * Common instance for {@code empty()}. |
| 48 | */ |
| 49 | private static final OptionalLong EMPTY = new OptionalLong(); |
| 50 | |
| 51 | /** |
| 52 | * If true then the value is present, otherwise indicates no value is present |
| 53 | */ |
| 54 | private final boolean isPresent; |
| 55 | private final long value; |
| 56 | |
| 57 | /** |
| 58 | * Construct an empty instance. |
| 59 | * |
| 60 | * @implNote generally only one empty instance, {@link OptionalLong#EMPTY}, |
| 61 | * should exist per VM. |
| 62 | */ |
| 63 | private OptionalLong() { |
| 64 | this.isPresent = false; |
| 65 | this.value = 0; |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * Returns an empty {@code OptionalLong} instance. No value is present for this |
| 70 | * OptionalLong. |
| 71 | * |
| 72 | * @apiNote Though it may be tempting to do so, avoid testing if an object |
| 73 | * is empty by comparing with {@code ==} against instances returned by |
| 74 | * {@code Option.empty()}. There is no guarantee that it is a singleton. |
| 75 | * Instead, use {@link #isPresent()}. |
| 76 | * |
| 77 | * @return an empty {@code OptionalLong}. |
| 78 | */ |
| 79 | public static OptionalLong empty() { |
| 80 | return EMPTY; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Construct an instance with the value present. |
| 85 | * |
| 86 | * @param value the long value to be present |
| 87 | */ |
| 88 | private OptionalLong(long value) { |
| 89 | this.isPresent = true; |
| 90 | this.value = value; |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Return an {@code OptionalLong} with the specified value present. |
| 95 | * |
| 96 | * @param value the value to be present |
| 97 | * @return an {@code OptionalLong} with the value present |
| 98 | */ |
| 99 | public static OptionalLong of(long value) { |
| 100 | return new OptionalLong(value); |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * If a value is present in this {@code OptionalLong}, returns the value, |
| 105 | * otherwise throws {@code NoSuchElementException}. |
| 106 | * |
| 107 | * @return the value held by this {@code OptionalLong} |
| 108 | * @throws NoSuchElementException if there is no value present |
| 109 | * |
| 110 | * @see OptionalLong#isPresent() |
| 111 | */ |
| 112 | public long getAsLong() { |
| 113 | if (!isPresent) { |
| 114 | throw new NoSuchElementException("No value present"); |
| 115 | } |
| 116 | return value; |
| 117 | } |
| 118 | |
| 119 | /** |
| 120 | * Return {@code true} if there is a value present, otherwise {@code false}. |
| 121 | * |
| 122 | * @return {@code true} if there is a value present, otherwise {@code false} |
| 123 | */ |
| 124 | public boolean isPresent() { |
| 125 | return isPresent; |
| 126 | } |
| 127 | |
| 128 | /** |
| 129 | * Have the specified consumer accept the value if a value is present, |
| 130 | * otherwise do nothing. |
| 131 | * |
| 132 | * @param consumer block to be executed if a value is present |
| 133 | * @throws NullPointerException if value is present and {@code consumer} is |
| 134 | * null |
| 135 | */ |
| 136 | public void ifPresent(LongConsumer consumer) { |
| 137 | if (isPresent) |
| 138 | consumer.accept(value); |
| 139 | } |
| 140 | |
| 141 | /** |
| 142 | * Return the value if present, otherwise return {@code other}. |
| 143 | * |
| 144 | * @param other the value to be returned if there is no value present |
| 145 | * @return the value, if present, otherwise {@code other} |
| 146 | */ |
| 147 | public long orElse(long other) { |
| 148 | return isPresent ? value : other; |
| 149 | } |
| 150 | |
| 151 | /** |
| 152 | * Return the value if present, otherwise invoke {@code other} and return |
| 153 | * the result of that invocation. |
| 154 | * |
| 155 | * @param other a {@code LongSupplier} whose result is returned if no value |
| 156 | * is present |
| 157 | * @return the value if present otherwise the result of {@code other.getAsLong()} |
| 158 | * @throws NullPointerException if value is not present and {@code other} is |
| 159 | * null |
| 160 | */ |
| 161 | public long orElseGet(LongSupplier other) { |
| 162 | return isPresent ? value : other.getAsLong(); |
| 163 | } |
| 164 | |
| 165 | /** |
| 166 | * Return the contained value, if present, otherwise throw an exception |
| 167 | * to be created by the provided supplier. |
| 168 | * |
| 169 | * @apiNote A method reference to the exception constructor with an empty |
| 170 | * argument list can be used as the supplier. For example, |
| 171 | * {@code IllegalStateException::new} |
| 172 | * |
| 173 | * @param <X> Type of the exception to be thrown |
| 174 | * @param exceptionSupplier The supplier which will return the exception to |
| 175 | * be thrown |
| 176 | * @return the present value |
| 177 | * @throws X if there is no value present |
| 178 | * @throws NullPointerException if no value is present and |
| 179 | * {@code exceptionSupplier} is null |
| 180 | */ |
| 181 | public<X extends Throwable> long orElseThrow(Supplier<X> exceptionSupplier) throws X { |
| 182 | if (isPresent) { |
| 183 | return value; |
| 184 | } else { |
| 185 | throw exceptionSupplier.get(); |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | /** |
| 190 | * Indicates whether some other object is "equal to" this OptionalLong. The |
| 191 | * other object is considered equal if: |
| 192 | * <ul> |
| 193 | * <li>it is also an {@code OptionalLong} and; |
| 194 | * <li>both instances have no value present or; |
| 195 | * <li>the present values are "equal to" each other via {@code ==}. |
| 196 | * </ul> |
| 197 | * |
| 198 | * @param obj an object to be tested for equality |
| 199 | * @return {code true} if the other object is "equal to" this object |
| 200 | * otherwise {@code false} |
| 201 | */ |
| 202 | @Override |
| 203 | public boolean equals(Object obj) { |
| 204 | if (this == obj) { |
| 205 | return true; |
| 206 | } |
| 207 | |
| 208 | if (!(obj instanceof OptionalLong)) { |
| 209 | return false; |
| 210 | } |
| 211 | |
| 212 | OptionalLong other = (OptionalLong) obj; |
| 213 | return (isPresent && other.isPresent) |
| 214 | ? value == other.value |
| 215 | : isPresent == other.isPresent; |
| 216 | } |
| 217 | |
| 218 | /** |
| 219 | * Returns the hash code value of the present value, if any, or 0 (zero) if |
| 220 | * no value is present. |
| 221 | * |
| 222 | * @return hash code value of the present value or 0 if no value is present |
| 223 | */ |
| 224 | @Override |
| 225 | public int hashCode() { |
| 226 | return isPresent ? Long.hashCode(value) : 0; |
| 227 | } |
| 228 | |
| 229 | /** |
| 230 | * {@inheritDoc} |
| 231 | * |
| 232 | * Returns a non-empty string representation of this object suitable for |
| 233 | * debugging. The exact presentation format is unspecified and may vary |
| 234 | * between implementations and versions. |
| 235 | * |
| 236 | * @implSpec If a value is present the result must include its string |
| 237 | * representation in the result. Empty and present instances must be |
| 238 | * unambiguously differentiable. |
| 239 | * |
| 240 | * @return the string representation of this instance |
| 241 | */ |
| 242 | @Override |
| 243 | public String toString() { |
| 244 | return isPresent |
| 245 | ? String.format("OptionalLong[%s]", value) |
| 246 | : "OptionalLong.empty"; |
| 247 | } |
| 248 | } |