org.gradle.performance.measure.Amount Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.performance.measure;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.List;
import java.util.Locale;
/**
* An amount is an immutable value of some quantity, such as duration or length. Each amount has a decimal value and associated units.
*
* TODO - need to sort out scaling when dividing or converting between units.
*/
public class Amount implements Comparable> {
// decimalFormat is not thread safe - synchronize access to the instance
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.###", new DecimalFormatSymbols(Locale.US));
private final BigDecimal value;
private final Units units;
private final BigDecimal normalised;
private String cachedToString;
private String cachedFormattedString;
private Amount(BigDecimal value, Units units) {
this.value = value;
this.units = units;
normalised = units.scaleTo(value, units.getBaseUnits());
}
public static Amount valueOf(long value, Units units) {
return valueOf(BigDecimal.valueOf(value), units);
}
/**
* Returns null if the given value is null.
*/
@Nullable
public static Amount valueOf(@Nullable BigDecimal value, Units units) {
if (value == null) {
return null;
}
return new Amount<>(value, units);
}
/**
* Returns a string representation of this amount. Uses the original value and units of this amount.
*/
@Override
public String toString() {
if (cachedToString == null) {
cachedToString = value + " " + units.format(value);
}
return cachedToString;
}
public Units getUnits() {
return units;
}
public BigDecimal getValue() {
return value;
}
/**
* Returns a human consumable string representation of this amount.
*/
public String format() {
if (cachedFormattedString == null) {
cachedFormattedString = doFormat();
}
return cachedFormattedString;
}
private String doFormat() {
List> allUnits = units.getUnitsForQuantity();
BigDecimal base = normalised.abs();
for (int i = allUnits.size()-1; i >= 0; i--) {
Units candidate = allUnits.get(i);
if (base.compareTo(candidate.getFactor()) >= 0) {
BigDecimal scaled = units.scaleTo(value, candidate);
return formatValue(scaled) + " " + candidate.format(scaled);
}
}
return formatValue(value) + " " + units.format(value);
}
private static String formatValue(BigDecimal value) {
synchronized (DECIMAL_FORMAT) {
return DECIMAL_FORMAT.format(value);
}
}
/**
* Converts this amount to an equivalent amount in the specified units.
*
* @return The converted amount.
*/
public Amount toUnits(Units units) {
if (units.equals(this.units)) {
return this;
}
return new Amount<>(this.units.scaleTo(value, units), units);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != getClass()) {
return false;
}
@SuppressWarnings("unchecked")
Amount other = (Amount) obj;
return compareTo(other) == 0;
}
@Override
public int hashCode() {
return normalised.hashCode();
}
@Override
public int compareTo(Amount o) {
if (o.units.getType() != units.getType()) {
throw new IllegalArgumentException(String.format("Cannot compare amount with units %s.", o.units));
}
return normalised.compareTo(o.normalised);
}
public Amount plus(Amount other) {
if (other.value.equals(BigDecimal.ZERO)) {
return this;
}
if (value.equals(BigDecimal.ZERO)) {
return other;
}
int diff = units.compareTo(other.units);
if (diff == 0) {
return new Amount<>(value.add(other.value), units);
}
if (diff < 0) {
return new Amount<>(value.add(other.units.scaleTo(other.value, units)), units);
}
return new Amount<>(units.scaleTo(value, other.units).add(other.value), other.units);
}
public Amount minus(Amount other) {
if (other.value.equals(BigDecimal.ZERO)) {
return this;
}
int diff = units.compareTo(other.units);
if (diff == 0) {
return new Amount<>(value.subtract(other.value), units);
}
if (diff < 0) {
return new Amount<>(value.subtract(other.units.scaleTo(other.value, units)), units);
}
return new Amount<>(units.scaleTo(value, other.units).subtract(other.value), other.units);
}
public Amount multiply(BigDecimal other) {
return new Amount<>(value.multiply(other), units);
}
public Amount div(long other) {
return div(BigDecimal.valueOf(other));
}
public Amount div(BigDecimal other) {
return new Amount<>(value.divide(other, 6, RoundingMode.HALF_UP), units);
}
public BigDecimal div(Amount other) {
return normalised.divide(other.normalised, 6, RoundingMode.HALF_UP);
}
public Amount abs() {
if (value.compareTo(BigDecimal.ZERO) >= 0) {
return this;
}
return new Amount<>(value.abs(), units);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy