Java tutorial
/* * Copyright 2014 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 com.carlomicieli.jtrains.value.objects; import com.carlomicieli.jtrains.util.Helpers; import org.springframework.util.Assert; import java.text.DecimalFormat; import java.util.Objects; /** * @author Carlo Micieli */ public final class Length { public final static MeasureUnit MILLIMETERS = millimetersUnit(); public final static MeasureUnit INCHES = inchesUnit(); private final static double MM_TO_INCHES = 0.0393700787; private final static double INCHES_TO_MM = 25.4; private final DecimalNumber mm; private final DecimalNumber inches; private Length(double m, double i) { this(DecimalNumber.valueOf(m), DecimalNumber.valueOf(i)); } private Length(DecimalNumber mm, DecimalNumber inches) { Assert.isTrue(mm.isPositive()); Assert.isTrue(inches.isPositive()); this.mm = mm; this.inches = inches; } public static Length valueOf(double val, MeasureUnit unit) { return new Length(unit.toMillimeters(val), unit.toInches(val)); } public double mm() { return mm.doubleValue(); } public double inches() { return inches.doubleValue(); } @Override public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof Length)) return false; Length that = (Length) obj; return Objects.equals(this.mm, that.mm) && Objects.equals(this.inches, that.inches); } @Override public int hashCode() { return Objects.hash(this.mm, this.inches); } @Override public String toString() { return Helpers.toStringBuilder(Length.class, sb -> sb.add("mm", mm).add("in", inches)); } private static interface MeasureUnit { double toInches(double v); double toMillimeters(double v); } private static MeasureUnit millimetersUnit() { return new MeasureUnit() { @Override public double toInches(double v) { return round(v * MM_TO_INCHES); } @Override public double toMillimeters(double v) { return v; } }; } private static MeasureUnit inchesUnit() { return new MeasureUnit() { @Override public double toInches(double v) { return v; } @Override public double toMillimeters(double v) { return round(v * INCHES_TO_MM); } }; } private static double round(double v) { DecimalFormat df = new DecimalFormat("#.##"); return Double.valueOf(df.format(v)); } }