001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.commons.lang; 018 019import static org.apache.juneau.commons.utils.AssertionUtils.*; 020import static org.apache.juneau.commons.utils.Utils.*; 021 022import java.util.concurrent.atomic.*; 023 024/** 025 * A simple mutable short value. 026 * 027 * <p> 028 * This class extends {@link Value}<{@link Short}> and adds a convenience method for incrementing 029 * the value, which is useful for counting operations in lambdas and loops. 030 * 031 * <h5 class='section'>Notes:</h5><ul> 032 * <li class='note'> 033 * This class is <b>not thread-safe</b>. For concurrent access, use {@link AtomicInteger} instead. 034 * </ul> 035 * 036 * <h5 class='section'>Example:</h5> 037 * <p class='bjava'> 038 * <jc>// Create a counter</jc> 039 * ShortValue <jv>counter</jv> = ShortValue.<jsm>create</jsm>(); 040 * 041 * <jc>// Use in a lambda to count valid items</jc> 042 * list.forEach(<jv>x</jv> -> { 043 * <jk>if</jk> (<jv>x</jv>.isValid()) { 044 * <jv>counter</jv>.getAndIncrement(); 045 * } 046 * }); 047 * 048 * <jsm>log</jsm>(<js>"Valid items: "</js> + <jv>counter</jv>.get()); 049 * </p> 050 * 051 * <h5 class='section'>See Also:</h5><ul> 052 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauCommonsLang">Lang Package</a> 053 * </ul> 054 */ 055public class ShortValue extends Value<Short> { 056 057 /** 058 * Creates a new short value initialized to <c>0</c>. 059 * 060 * <h5 class='section'>Example:</h5> 061 * <p class='bjava'> 062 * ShortValue <jv>counter</jv> = ShortValue.<jsm>create</jsm>(); 063 * <jsm>assertEquals</jsm>(0, <jv>counter</jv>.get()); 064 * </p> 065 * 066 * @return A new short value. 067 */ 068 public static ShortValue create() { 069 return of((short)0); 070 } 071 072 /** 073 * Creates a new short value with the specified initial value. 074 * 075 * <h5 class='section'>Example:</h5> 076 * <p class='bjava'> 077 * ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)42); 078 * <jsm>assertEquals</jsm>(42, <jv>counter</jv>.get()); 079 * </p> 080 * 081 * @param value The initial value. 082 * @return A new short value. 083 */ 084 public static ShortValue of(Short value) { 085 return new ShortValue(value); 086 } 087 088 /** 089 * Constructor. 090 * 091 * @param value The initial value. 092 */ 093 public ShortValue(Short value) { 094 super(value); 095 } 096 097 /** 098 * Adds the specified value to the current value. 099 * 100 * <h5 class='section'>Example:</h5> 101 * <p class='bjava'> 102 * ShortValue <jv>value</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)10); 103 * <jv>value</jv>.add((<jk>short</jk>)5); 104 * <jsm>assertEquals</jsm>(15, <jv>value</jv>.get()); 105 * </p> 106 * 107 * @param x The value to add. 108 * @return This object. 109 */ 110 public ShortValue add(Short x) { 111 var v = get(); 112 set((short)((v == null ? 0 : v) + (x == null ? 0 : x))); 113 return this; 114 } 115 116 /** 117 * Adds the specified value to the current value and returns the new value. 118 * 119 * <h5 class='section'>Example:</h5> 120 * <p class='bjava'> 121 * ShortValue <jv>value</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)10); 122 * <jk>short</jk> <jv>result</jv> = <jv>value</jv>.addAndGet((<jk>short</jk>)5); <jc>// Returns 15</jc> 123 * <jsm>assertEquals</jsm>(15, <jv>value</jv>.get()); 124 * </p> 125 * 126 * @param x The value to add. 127 * @return The new value after addition. 128 */ 129 public Short addAndGet(Short x) { 130 var v = get(); 131 var result = (short)((v == null ? 0 : v) + (x == null ? 0 : x)); 132 set(result); 133 return result; 134 } 135 136 /** 137 * Decrements the value by 1. 138 * 139 * <h5 class='section'>Example:</h5> 140 * <p class='bjava'> 141 * ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5); 142 * <jv>counter</jv>.decrement(); 143 * <jsm>assertEquals</jsm>(4, <jv>counter</jv>.get()); 144 * </p> 145 * 146 * @return This object. 147 */ 148 public ShortValue decrement() { 149 var v = get(); 150 set((short)((v == null ? 0 : v) - 1)); 151 return this; 152 } 153 154 /** 155 * Decrements the value by 1 and returns the new value. 156 * 157 * <h5 class='section'>Example:</h5> 158 * <p class='bjava'> 159 * ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5); 160 * <jk>short</jk> <jv>result</jv> = <jv>counter</jv>.decrementAndGet(); <jc>// Returns 4</jc> 161 * <jsm>assertEquals</jsm>(4, <jv>counter</jv>.get()); 162 * </p> 163 * 164 * @return The decremented value. 165 */ 166 public Short decrementAndGet() { 167 var v = get(); 168 var result = (short)((v == null ? 0 : v) - 1); 169 set(result); 170 return result; 171 } 172 173 /** 174 * Returns the current value and then increments it. 175 * 176 * <h5 class='section'>Example:</h5> 177 * <p class='bjava'> 178 * ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5); 179 * <jk>short</jk> <jv>current</jv> = <jv>counter</jv>.getAndIncrement(); <jc>// Returns 5</jc> 180 * <jk>short</jk> <jv>next</jv> = <jv>counter</jv>.get(); <jc>// Returns 6</jc> 181 * </p> 182 * 183 * @return The value before it was incremented. 184 */ 185 public short getAndIncrement() { 186 var v = get(); 187 set(v == null ? 1 : (short)(v + 1)); 188 return v == null ? 0 : v; 189 } 190 191 /** 192 * Increments the value by 1. 193 * 194 * <h5 class='section'>Example:</h5> 195 * <p class='bjava'> 196 * ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5); 197 * <jv>counter</jv>.increment(); 198 * <jsm>assertEquals</jsm>(6, <jv>counter</jv>.get()); 199 * </p> 200 * 201 * @return This object. 202 */ 203 public ShortValue increment() { 204 var v = get(); 205 set((short)((v == null ? 0 : v) + 1)); 206 return this; 207 } 208 209 /** 210 * Increments the value by 1 and returns the new value. 211 * 212 * <h5 class='section'>Example:</h5> 213 * <p class='bjava'> 214 * ShortValue <jv>counter</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5); 215 * <jk>short</jk> <jv>result</jv> = <jv>counter</jv>.incrementAndGet(); <jc>// Returns 6</jc> 216 * <jsm>assertEquals</jsm>(6, <jv>counter</jv>.get()); 217 * </p> 218 * 219 * @return The incremented value. 220 */ 221 public Short incrementAndGet() { 222 var v = get(); 223 var result = (short)((v == null ? 0 : v) + 1); 224 set(result); 225 return result; 226 } 227 228 /** 229 * Checks if the current value is equal to the specified value. 230 * 231 * <p> 232 * Uses {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)} for deep equality comparison, which handles nulls safely. 233 * 234 * <h5 class='section'>Example:</h5> 235 * <p class='bjava'> 236 * ShortValue <jv>value</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)42); 237 * <jsm>assertTrue</jsm>(<jv>value</jv>.is((<jk>short</jk>)42)); 238 * <jsm>assertFalse</jsm>(<jv>value</jv>.is((<jk>short</jk>)43)); 239 * </p> 240 * 241 * @param value The value to compare to. 242 * @return <jk>true</jk> if the current value is equal to the specified value. 243 */ 244 public boolean is(Short value) { 245 return eq(get(), value); 246 } 247 248 /** 249 * Checks if the current value matches any of the specified values. 250 * 251 * <p> 252 * Uses {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)} for deep equality comparison of each value. 253 * 254 * <h5 class='section'>Example:</h5> 255 * <p class='bjava'> 256 * ShortValue <jv>value</jv> = ShortValue.<jsm>of</jsm>((<jk>short</jk>)5); 257 * <jsm>assertTrue</jsm>(<jv>value</jv>.isAny((<jk>short</jk>)3, (<jk>short</jk>)5, (<jk>short</jk>)7)); 258 * <jsm>assertFalse</jsm>(<jv>value</jv>.isAny((<jk>short</jk>)1, (<jk>short</jk>)2)); 259 * </p> 260 * 261 * @param values The values to compare to. 262 * @return <jk>true</jk> if the current value matches any of the specified values. 263 */ 264 public boolean isAny(Short...values) { 265 assertArgNotNull("values", values); 266 var current = get(); 267 for (var value : values) 268 if (eq(current, value)) 269 return true; 270 return false; 271 } 272}