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 022/** 023 * A simple mutable byte value. 024 * 025 * <p> 026 * This class extends {@link Value}<{@link Byte}> and adds convenience methods for incrementing, 027 * decrementing, and testing byte values, which are useful in lambdas and byte manipulation operations. 028 * 029 * <h5 class='section'>Notes:</h5><ul> 030 * <li class='note'> 031 * This class is <b>not thread-safe</b>. For concurrent access, use synchronization or atomic classes. 032 * </ul> 033 * 034 * <h5 class='section'>Example:</h5> 035 * <p class='bjava'> 036 * <jc>// Create a counter</jc> 037 * ByteValue <jv>counter</jv> = ByteValue.<jsm>create</jsm>(); 038 * 039 * <jc>// Use in a lambda to count items</jc> 040 * list.forEach(<jv>x</jv> -> { 041 * <jk>if</jk> (<jv>x</jv>.isValid()) { 042 * <jv>counter</jv>.increment(); 043 * } 044 * }); 045 * 046 * <jsm>log</jsm>(<js>"Count: "</js> + <jv>counter</jv>.get()); 047 * </p> 048 * 049 * <h5 class='section'>See Also:</h5><ul> 050 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauCommonsLang">Lang Package</a> 051 * </ul> 052 */ 053public class ByteValue extends Value<Byte> { 054 055 /** 056 * Creates a new byte value initialized to <c>0</c>. 057 * 058 * <h5 class='section'>Example:</h5> 059 * <p class='bjava'> 060 * ByteValue <jv>counter</jv> = ByteValue.<jsm>create</jsm>(); 061 * <jsm>assertEquals</jsm>(0, <jv>counter</jv>.get()); 062 * </p> 063 * 064 * @return A new byte value. 065 */ 066 public static ByteValue create() { 067 return of((byte)0); 068 } 069 070 /** 071 * Creates a new byte value with the specified initial value. 072 * 073 * <h5 class='section'>Example:</h5> 074 * <p class='bjava'> 075 * ByteValue <jv>value</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)42); 076 * <jsm>assertEquals</jsm>(42, <jv>value</jv>.get()); 077 * </p> 078 * 079 * @param value The initial value. 080 * @return A new byte value. 081 */ 082 public static ByteValue of(Byte value) { 083 return new ByteValue(value); 084 } 085 086 /** 087 * Constructor. 088 */ 089 public ByteValue() { 090 super((byte)0); 091 } 092 093 /** 094 * Constructor. 095 * 096 * @param value The initial value. 097 */ 098 public ByteValue(Byte value) { 099 super(value == null ? 0 : value); 100 } 101 102 /** 103 * Adds the specified value to the current value. 104 * 105 * <h5 class='section'>Example:</h5> 106 * <p class='bjava'> 107 * ByteValue <jv>value</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)10); 108 * <jv>value</jv>.add((<jk>byte</jk>)5); 109 * <jsm>assertEquals</jsm>(15, <jv>value</jv>.get()); 110 * </p> 111 * 112 * @param x The value to add. 113 * @return This object. 114 */ 115 public ByteValue add(Byte x) { 116 set((byte)(get() + (x == null ? 0 : x))); 117 return this; 118 } 119 120 /** 121 * Adds the specified value to the current value and returns the new value. 122 * 123 * <h5 class='section'>Example:</h5> 124 * <p class='bjava'> 125 * ByteValue <jv>value</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)10); 126 * <jk>byte</jk> <jv>result</jv> = <jv>value</jv>.addAndGet((<jk>byte</jk>)5); <jc>// Returns 15</jc> 127 * <jsm>assertEquals</jsm>(15, <jv>value</jv>.get()); 128 * </p> 129 * 130 * @param x The value to add. 131 * @return The new value after addition. 132 */ 133 public Byte addAndGet(Byte x) { 134 set((byte)(get() + (x == null ? 0 : x))); 135 return get(); 136 } 137 138 /** 139 * Decrements the value by 1. 140 * 141 * <h5 class='section'>Example:</h5> 142 * <p class='bjava'> 143 * ByteValue <jv>counter</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)5); 144 * <jv>counter</jv>.decrement(); 145 * <jsm>assertEquals</jsm>(4, <jv>counter</jv>.get()); 146 * </p> 147 * 148 * @return This object. 149 */ 150 public ByteValue decrement() { 151 set((byte)(get() - 1)); 152 return this; 153 } 154 155 /** 156 * Decrements the value by 1 and returns the new value. 157 * 158 * <h5 class='section'>Example:</h5> 159 * <p class='bjava'> 160 * ByteValue <jv>counter</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)5); 161 * <jk>byte</jk> <jv>result</jv> = <jv>counter</jv>.decrementAndGet(); <jc>// Returns 4</jc> 162 * <jsm>assertEquals</jsm>(4, <jv>counter</jv>.get()); 163 * </p> 164 * 165 * @return The decremented value. 166 */ 167 public Byte decrementAndGet() { 168 set((byte)(get() - 1)); 169 return get(); 170 } 171 172 /** 173 * Increments the value by 1. 174 * 175 * <h5 class='section'>Example:</h5> 176 * <p class='bjava'> 177 * ByteValue <jv>counter</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)5); 178 * <jv>counter</jv>.increment(); 179 * <jsm>assertEquals</jsm>(6, <jv>counter</jv>.get()); 180 * </p> 181 * 182 * @return This object. 183 */ 184 public ByteValue increment() { 185 set((byte)(get() + 1)); 186 return this; 187 } 188 189 /** 190 * Increments the value by 1 and returns the new value. 191 * 192 * <h5 class='section'>Example:</h5> 193 * <p class='bjava'> 194 * ByteValue <jv>counter</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)5); 195 * <jk>byte</jk> <jv>result</jv> = <jv>counter</jv>.incrementAndGet(); <jc>// Returns 6</jc> 196 * <jsm>assertEquals</jsm>(6, <jv>counter</jv>.get()); 197 * </p> 198 * 199 * @return The incremented value. 200 */ 201 public Byte incrementAndGet() { 202 set((byte)(get() + 1)); 203 return get(); 204 } 205 206 /** 207 * Checks if the current value is equal to the specified value. 208 * 209 * <p> 210 * Uses {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)} for deep equality comparison, which handles nulls safely. 211 * 212 * <h5 class='section'>Example:</h5> 213 * <p class='bjava'> 214 * ByteValue <jv>value</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)42); 215 * <jsm>assertTrue</jsm>(<jv>value</jv>.is((<jk>byte</jk>)42)); 216 * <jsm>assertFalse</jsm>(<jv>value</jv>.is((<jk>byte</jk>)43)); 217 * </p> 218 * 219 * @param value The value to compare to. 220 * @return <jk>true</jk> if the current value is equal to the specified value. 221 */ 222 public boolean is(Byte value) { 223 return eq(get(), value); 224 } 225 226 /** 227 * Checks if the current value matches any of the specified values. 228 * 229 * <p> 230 * Uses {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)} for deep equality comparison of each value. 231 * 232 * <h5 class='section'>Example:</h5> 233 * <p class='bjava'> 234 * ByteValue <jv>value</jv> = ByteValue.<jsm>of</jsm>((<jk>byte</jk>)5); 235 * <jsm>assertTrue</jsm>(<jv>value</jv>.isAny((<jk>byte</jk>)3, (<jk>byte</jk>)5, (<jk>byte</jk>)7)); 236 * <jsm>assertFalse</jsm>(<jv>value</jv>.isAny((<jk>byte</jk>)1, (<jk>byte</jk>)2)); 237 * </p> 238 * 239 * @param values The values to compare to. 240 * @return <jk>true</jk> if the current value matches any of the specified values. 241 */ 242 public boolean isAny(Byte...values) { 243 assertArgNotNull("values", values); 244 var current = get(); 245 for (var value : values) 246 if (eq(current, value)) 247 return true; 248 return false; 249 } 250}