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

com.hwaipy.quantity.Unit Maven / Gradle / Ivy

The newest version!
package com.hwaipy.quantity;

import static com.hwaipy.quantity.SIBaseUnit.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;

/**
 *
 * @author Hwaipy
 */
public class Unit {

  private final String token;
  private final boolean hasPrefix;
  private final double factor;
  private final int[] powers = new int[7];

  public Unit(String token, boolean hasPrefix, double factor,
          int powerM, int powerKG, int powerS, int powerA,
          int powerK, int powerMOL, int powerCD) {
    this.token = token;
    this.hasPrefix = hasPrefix;
    this.factor = factor;
    powers[m.ordinal()] = powerM;
    powers[kg.ordinal()] = powerKG;
    powers[s.ordinal()] = powerS;
    powers[A.ordinal()] = powerA;
    powers[K.ordinal()] = powerK;
    powers[mol.ordinal()] = powerMOL;
    powers[cd.ordinal()] = powerCD;
  }

  public String getToken() {
    return token;
  }

  public boolean hasPrefix() {
    return hasPrefix;
  }

  public double getFactor() {
    return factor;
  }

  public int getPower(SIBaseUnit unit) {
    return powers[unit.ordinal()];
  }

  public int[] getPowers(SIBaseUnit... units) {
    int[] result = new int[units.length];
    for (int i = 0; i < units.length; i++) {
      result[i] = powers[units[i].ordinal()];
    }
    return result;
  }

  public int[] getPowers() {
    return getPowers(m, kg, s, A, K, mol, cd);
  }

  public Unit prefix(UnitPrefix prefix) throws QuantityException {
    if (this.hasPrefix) {
      return new UnitBuilder(this).setHasPrefix(false)
              .setFactor(factor * prefix.getFactor()).createUnit();
    }
    else {
      throw new QuantityException("Unit " + this.getToken() + " can not has prefix.");
    }
  }

  public void assertDimension(String dimension) throws UnitDimensionMissmatchException, QuantityParseException {
    if (!equalsDimension(of(dimension))) {
      throw new UnitDimensionMissmatchException("Assertion failed. Expected [" + dimension + "], get [" + toDimensionString() + "]");
    }
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null || this.getClass() != obj.getClass()) {
      return false;
    }
    Unit unit = (Unit) obj;
    if (this.token == null) {
      if (unit.token != null) {
        return false;
      }
    }
    else {
      if (!this.token.equals(unit.token)) {
        return false;
      }
    }
    if (this.hasPrefix != unit.hasPrefix) {
      return false;
    }
    if (this.factor != unit.factor) {
      return false;
    }
    return equalsDimension(unit);
  }

  public boolean equalsDimension(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null || this.getClass() != obj.getClass()) {
      return false;
    }
    Unit unit = (Unit) obj;
    for (int i = 0; i < powers.length; i++) {
      if (powers[i] != unit.powers[i]) {
        return false;
      }
    }
    return true;
  }

  public boolean isDimentionless() {
    for (int power : powers) {
      if (power != 0) {
        return false;
      }
    }
    return true;
  }

  @Override
  public int hashCode() {
    int hash = 7;
    hash = 83 * hash + Objects.hashCode(this.token);
    hash = 83 * hash + (this.hasPrefix ? 1 : 0);
    hash = 83 * hash + (int) (Double.doubleToLongBits(this.factor) ^ (Double.doubleToLongBits(this.factor) >>> 32));
    hash = 83 * hash + Arrays.hashCode(this.powers);
    return hash;
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("Unit[").append(token).append(",").append(hasPrefix).append(",")
            .append(factor).append(",").append(toDimensionString()).append("]");
    return sb.toString();
  }

  public String toDimensionString() {
    String dimensionString = doGetDimensionString();
    return dimensionString.length() == 0 ? "1" : dimensionString;
  }

  public String toUnitString() {
    StringBuilder stringBuilder = new StringBuilder();
    if (factor != 1) {
      stringBuilder.append(factor);
    }
    stringBuilder.append(doGetDimensionString());
    if (stringBuilder.length() == 0) {
      return "1";
    }
    return stringBuilder.toString();
  }

  private String doGetDimensionString() {
    StringBuilder stringBuilder = new StringBuilder();
    ArrayList powersList = new ArrayList<>();
    SIBaseUnit[] baseUnits = SIBaseUnit.values();
    int countOfSiBaseUnit = baseUnits.length;
    for (int i = 0; i < powers.length; i++) {
      powersList.add((powers[i] + 1) * countOfSiBaseUnit - i - 1);
    }
    Collections.sort(powersList);
    Collections.reverse(powersList);
    boolean firstDimension = true;
    for (Integer powerIndex : powersList) {
      int power = powerIndex / countOfSiBaseUnit;
      int unitIndex = countOfSiBaseUnit - powerIndex % countOfSiBaseUnit - 1;
      if (unitIndex >= countOfSiBaseUnit) {
        power -= 1;
        unitIndex -= countOfSiBaseUnit;
      }
      SIBaseUnit unit = baseUnits[unitIndex];
      if (power != 0) {
        if (firstDimension) {
          firstDimension = false;
        }
        else {
          stringBuilder.append("⋅");
        }
        stringBuilder.append(unit);
        if (power != 1) {
          stringBuilder.append("^").append(power);
        }
      }
    }
    return stringBuilder.toString();
  }

  public Unit times(Unit unit) {
    return new UnitBuilder(this).times(unit).createUnit();
  }

  public Unit times(Unit unit, int power) {
    return new UnitBuilder(this).times(unit, power).createUnit();
  }

  public Unit power(int power) {
    return new UnitBuilder().times(this, power).createUnit();
  }

  public Unit divide(Unit unit) {
    return new UnitBuilder(this).divide(unit).createUnit();
  }

  public Unit divide(Unit unit, int power) {
    return new UnitBuilder(this).divide(unit, power).createUnit();
  }

  public static Unit of(String unitString) throws QuantityParseException {
    return new QuantityParser(unitString).parseUnit(true);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy