jlibs.core.lang.Count Maven / Gradle / Ivy
/**
* Copyright 2015 Santhosh Kumar Tekuri
*
* The JLibs authors license this file to you 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 jlibs.core.lang;
import java.util.Arrays;
/**
* Class used to count by units
*
* @author Santhosh Kumar T
*/
public class Count implements Comparable>{
private long amounts[];
private T units[];
private Count(T units[]){
this.units = units;
amounts = new long[units.length];
}
static interface Unit{
public int ordinal();
public int count();
public String toString();
}
public static Count newInstance(Class unitClass){
if(!unitClass.isEnum())
throw new IllegalArgumentException(unitClass+" should be enum");
return new Count(unitClass.getEnumConstants());
}
/*-------------------------------------------------[ Manipulation ]---------------------------------------------------*/
public Count add(long amount, T unit){
if(amount<0)
throw new IllegalArgumentException("amount '"+amount+"' should be >=0");
if(amount>0){
amounts[unit.ordinal()] += amount;
for(int i=unit.ordinal(); i=units[i].count()){
amounts[i+1] += amounts[i] / units[i].count();
amounts[i] %= units[i].count();
}else
break;
}
}
return this;
}
public Count add(Count other){
for(T unit: units)
add(other.amounts[unit.ordinal()], unit);
return this;
}
public Count clear(){
Arrays.fill(amounts, 0);
return this;
}
public Count set(long amount, T unit){
if(amount<0)
throw new IllegalArgumentException("amount '"+amount+"' should be >=0");
return clear().add(amount, unit);
}
public Count set(Count other){
return clear().add(other);
}
/*-------------------------------------------------[ Getters ]---------------------------------------------------*/
public long get(T unit){
return amounts[unit.ordinal()];
}
public strictfp double to(T unit){
long value = amounts[units.length-1];
for(int i=units.length-2; i>=unit.ordinal(); i--)
value = amounts[i]+ units[i].count()*value;
if(unit.ordinal()>0){
double before = amounts[0];
for(int i=1; i>>32);
}
@Override
public boolean equals(Object obj){
if(obj instanceof Count){
Count> that = (Count>)obj;
return Arrays.equals(this.units, that.units) && Arrays.equals(this.amounts, that.amounts);
}
return false;
}
public String toString(){
StringBuilder buff = new StringBuilder();
for(int i=units.length-1; i>=0; i--){
if(amounts[i]>0){
if(buff.length()>0)
buff.append(' ');
buff.append(amounts[i]);
buff.append(' ');
buff.append(units[i]);
}
}
return buff.length()==0 ? "0 "+units[0] : buff.toString();
}
/*-------------------------------------------------[ Comparable ]---------------------------------------------------*/
@Override
public int compareTo(Count that){
for(int i=units.length-1; i>=0; i--){
if(this.amounts[i]!=that.amounts[i])
return this.amounts[i]