All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.freeutils.util.Utils Maven / Gradle / Ivy

The newest version!
/*
 *  Copyright © 2003-2024 Amichai Rothman
 *
 *  This file is part of JElementary - the Java Elementary Utilities package.
 *
 *  JElementary is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  JElementary is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with JElementary.  If not, see .
 *
 *  For additional info see https://www.freeutils.net/source/jelementary/
 */

package net.freeutils.util;

import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

/**
 * The {@code Utils} class contains general utility methods.
 */
public class Utils {

    /**
     * A publicly available Random instance, for generating random
     * data (thread-safe and unique within the JVM process).
     */
    public static final Random rand = new Random();

    /**
     * An AtomicLong used for generating JVM-unique sequence numbers.
     */
    private static final AtomicLong sequence = new AtomicLong();

    /**
     * Private constructor to avoid external instantiation.
     */
    private Utils() {}

    /**
     * Returns whether the two given objects are equal.
     * 

* Equality is determined by first making the reference comparison {@code a == b}, * and if it fails and the first object is not null, by calling {@code a.equals(b)}. * This provides several advantages over a regular call to {@code a.equals(b)}: *

    *
  • increased efficiency for objects whose {@code equals} method does not * include the optimization of using reference comparison *
  • null safety in that the {@code equals} method is never invoked on a null reference *
  • two null references can be safely checked for equality *
* * @param a the first object * @param b the second object * @return true if the objects are equal, false otherwise */ public static boolean equals(Object a, Object b) { return a == b || a != null && a.equals(b); } /** * Returns the given object if it is not null, otherwise the second object. * * @param the object's type * @param obj the object * @param def the alternate (default) object * @return obj if it is not null, otherwise def */ public static T def(T obj, T def) { return obj != null ? obj : def; } /** * Returns an increasing sequence number, starting with {@code 1}. * The sequence overflows after reaching {@code Long.MAX_VALUE}. *

* This method can be used to return up to 264 values * which are unique within the JVM instance. * * @return the next sequence number */ public static long nextSequence() { return sequence.incrementAndGet(); } /** * Returns the given object if it is not null. * * @param the object type * @param obj an object * @return the object if it is not null * @throws NullPointerException if the object is null */ public static T notNull(T obj) { if (obj == null) throw new NullPointerException("invalid object (null)"); return obj; } /** * Parses an unsigned long value. This method behaves the same as calling * {@link Long#parseLong(String, int)}, but considers the string invalid * if it starts with an ASCII minus sign ('-') or plus sign ('+'). * * @param s the String containing the long representation to be parsed * @param radix the radix to be used while parsing s * @return the long represented by s in the specified radix * @throws NumberFormatException if the string does not contain a parsable * long, or if it starts with an ASCII minus sign or plus sign */ public static long parseULong(String s, int radix) throws NumberFormatException { long val = Long.parseLong(s, radix); // throws NumberFormatException if (s.charAt(0) == '-' || s.charAt(0) == '+') throw new NumberFormatException("invalid digit: " + s.charAt(0)); return val; } /** * Parses a long value in the given range. * * @param s the String containing the long representation to be parsed * @param radix the radix to be used while parsing s * @param min the minimum allowed value (inclusive) * @param max the maximum allowed value (inclusive) * @return the long represented by s in the specified radix * @throws NumberFormatException if the string does not contain a parsable * long, or it is outside the given range */ public static long parseLong(String s, int radix, long min, long max) throws NumberFormatException { long i = Long.parseLong(s, radix); // throws NumberFormatException if (i < min || i > max) throw new NumberFormatException("number out of range (" + s + " not in [" + min + "," + max + "])"); return i; } /** * Parses an array of ints. * * @param arr the array to parse * @return the parsed array of ints * @throws NumberFormatException if one of the strings does not contain a parsable integer */ public static int[] parseInts(String... arr) { int[] res = new int[arr.length]; for (int i = 0; i < arr.length; i++) res[i] = Integer.parseInt(arr[i]); return res; } /** * Parses an array of unsigned decimal byte values. * * @param arr the array to parse * @return the parsed array of bytes * @throws NumberFormatException if one of the strings does not contain a parsable unsigned byte */ public static byte[] parseUBytes(String... arr) { byte[] res = new byte[arr.length]; for (int i = 0; i < arr.length; i++) { int b = Integer.parseInt(arr[i]); if (b < 0 || b > 255) throw new NumberFormatException("invalid unsigned byte value: " + arr[i]); res[i] = (byte)b; } return res; } /** * Parses an int value using {@link Integer#parseInt}. If the given string * is null or empty, the given default is returned. If the string cannot * be parsed as an integer, an exception is thrown. * * @param s a String containing the int * representation to be parsed * @param def the default value to return if s is null or empty * @return the parsed integer value, or the default value if the string is null or empty * @throws NumberFormatException if the string does not contain a parsable integer */ public static int parseInt(String s, int def) throws NumberFormatException { return s == null || s.isEmpty() ? def : Integer.parseInt(s); } /** * Parses a boolean value using {@link Boolean#parseBoolean}. If the given string * is null or empty, the given default is returned. If the string cannot * be parsed as a boolean, an exception is thrown. * * @param s a String containing the boolean * representation to be parsed * @param def the default value to return if s is null or empty * @return the parsed boolean value, or the default value if the string is null or empty */ public static boolean parseBoolean(String s, boolean def) { return s == null || s.isEmpty() ? def : Boolean.parseBoolean(s); } /** * Returns an unsigned 8-bit value from a byte array. * * @param buf a byte array from which byte value is taken * @param offset the offset within buf from which byte value is taken * @return an unsigned 8-bit value as an int */ public static int getU8(byte[] buf, int offset) { return buf[offset] & 0xFF; } /** * Returns an unsigned 16-bit value from its constituent bytes. * * @param b1 first byte value * @param b2 second byte value * @param lsb specifies if the bytes are interpreted in LSB or MSB order * @return an unsigned 16-bit value as an int */ public static int getU16(int b1, int b2, boolean lsb) { return lsb ? ((b1 & 0xFF) | ((b2 & 0xFF) << 8)) & 0xFFFF : ((b2 & 0xFF) | ((b1 & 0xFF) << 8)) & 0xFFFF; } /** * Returns an unsigned 16-bit value read from a byte array. * * @param buf a byte array from which byte values are taken * @param offset the offset within buf from which byte values are taken * @param lsb specifies if the bytes are interpreted in LSB or MSB order * @return an unsigned 16-bit value as an int */ public static int getU16(byte[] buf, int offset, boolean lsb) { return lsb ? ((buf[offset] & 0xFF) | ((buf[offset + 1] & 0xFF) << 8)) & 0xFFFF : ((buf[offset + 1] & 0xFF) | ((buf[offset] & 0xFF) << 8)) & 0xFFFF; } /** * Returns an unsigned 32-bit value from its constituent bytes. * * @param b1 first byte value * @param b2 second byte value * @param b3 third byte value * @param b4 fourth byte value * @param lsb specifies if the bytes are interpreted in LSB or MSB order * @return an unsigned 32-bit value as a long */ public static long getU32(int b1, int b2, int b3, int b4, boolean lsb) { return lsb ? ((b1 & 0xFF) | ((b2 & 0xFF) << 8) | ((b3 & 0xFF) << 16) | ((b4 & 0xFF) << 24)) & 0x00000000FFFFFFFFL : ((b4 & 0xFF) | ((b3 & 0xFF) << 8) | ((b2 & 0xFF) << 16) | ((b1 & 0xFF) << 24)) & 0x00000000FFFFFFFFL; } /** * Returns an unsigned 32-bit value read from a byte array. * * @param buf a byte array from which byte values are taken * @param offset the offset within buf from which byte values are taken * @param lsb specifies if the bytes are interpreted in LSB or MSB order * @return an unsigned 32-bit value as a long */ public static long getU32(byte[] buf, int offset, boolean lsb) { return lsb ? ((buf[offset] & 0xFF) | ((buf[offset + 1] & 0xFF) << 8) | ((buf[offset + 2] & 0xFF) << 16) | ((buf[offset + 3] & 0xFF) << 24)) & 0x00000000FFFFFFFFL : ((buf[offset + 3] & 0xFF) | ((buf[offset + 2] & 0xFF) << 8) | ((buf[offset + 1] & 0xFF) << 16) | ((buf[offset] & 0xFF) << 24)) & 0x00000000FFFFFFFFL; } /** * Returns a 64-bit value read from a byte array. * * @param buf a byte array from which byte values are taken * @param offset the offset within buf from which byte values are taken * @param lsb specifies if the bytes are interpreted in LSB or MSB order * @return a 64-bit value as a long */ public static long getU64(byte[] buf, int offset, boolean lsb) { return lsb ? ((getU32(buf, offset + 4, true) & 0x00000000FFFFFFFFL) << 32) | (getU32(buf, offset, true) & 0x00000000FFFFFFFFL) : ((getU32(buf, offset, false) & 0x00000000FFFFFFFFL) << 32) | (getU32(buf, offset + 4, false) & 0x00000000FFFFFFFFL); } /** * Returns the signum function of the argument; zero if the argument * is zero, 1 if the argument is greater than zero, -1 if the * argument is less than zero. * * @param i the value whose signum is to be returned * @return the signum function of the argument */ public static int signum(long i) { return i < 0 ? -1 : i > 0 ? 1 : 0; } /** * Returns the bytes of the given value as a byte array. * * @param value the value * @param lsb specifies if the bytes are returned in LSB or MSB order * @param b the byte array into which the bytes are written * @param offset the offset in the byte array where the bytes are written * @param len the number of byte to write (always taken from the lower-order bytes of the value) * @return the b array containing the value bytes */ public static byte[] getBytes(long value, boolean lsb, byte[] b, int offset, int len) { if (lsb) { for (int i = offset, max = offset + len; i < max; i++) { b[i] = (byte)value; value >>>= 8; } } else { for (int i = offset + len - 1; i >= offset; i--) { b[i] = (byte)value; value >>>= 8; } } return b; } /** * Returns the bytes of the given value as a byte array. * * @param value the value * @param lsb specifies if the bytes are returned in LSB or MSB order * @param b the byte array into which the bytes are written, starting * at offset zero; the number of written bytes n depends on the size * of the array (always taken from the lower-order n bytes of the value) * @return the b array containing the value bytes */ public static byte[] getBytes(long value, boolean lsb, byte[] b) { return getBytes(value, lsb, b, 0, b.length); } /** * Returns the bytes of the given value as a byte array. * * @param value the value * @param lsb specifies if the bytes are returned in LSB or MSB order * @param len the number of bytes to return (bytes are always taken * from the lower-order bytes of the value) * @return an array containing the value bytes */ public static byte[] getBytes(long value, boolean lsb, int len) { return getBytes(value, lsb, new byte[len]); } /** * Returns the bytes of the given long value as a byte array. * * @param value the value * @param lsb specifies if the bytes are returned in LSB or MSB order * @return an array containing the 8 long value bytes */ public static byte[] getBytes(long value, boolean lsb) { return getBytes(value, lsb, 8); } /** * Returns the bytes of the given int value as a byte array. * * @param value the value * @param lsb specifies if the bytes are returned in LSB or MSB order * @return an array containing the 4 int value bytes */ public static byte[] getBytes(int value, boolean lsb) { return getBytes(value, lsb, 4); } /** * Returns a bitmask with given number of high-order bits set. * * @param bits the number of high-order bits to set in the bitmask * @return the bitmask with the given number of high-order bits set * @throws IllegalArgumentException if given number of bits is * negative or greater than 32 */ public static byte[] getMask32(int bits) { if (bits < 0 || bits > 32) throw new IllegalArgumentException("invalid bitmask " + bits); int mask = -(1 << (32 - bits)); return new byte[] { (byte)((mask >> 24) & 0xFF), (byte)((mask >> 16) & 0xFF), (byte)((mask >> 8) & 0xFF), (byte)(mask & 0xFF) }; } /** * Returns the result of an AND operation between the corresponding bytes * in the two given arrays. * * @param bytes an array of bytes * @param mask an array of bytes * @return a new array which is the result of performing the AND operation * between the corresponding bytes in the two arrays * @throws IllegalArgumentException if the arrays have different lengths */ public static byte[] and(byte[] bytes, byte[] mask) { int len = bytes.length; if (mask.length != len) throw new IllegalArgumentException("mismatched number of bytes"); byte[] res = new byte[len]; for (int i = 0; i < len; i++) res[i] = (byte)(bytes[i] & mask[i]); return res; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy