package com.snowcattle.game.common.util;
import java.util.BitSet;
/**
* 基本数组实现的数值属性值对象
*
*
*/
public final class IntNumberPropertyArray implements Cloneable {
/** 保存数值 */
private final int[] values;
/** 数值是否修改的标识 */
private final BitSet bitSet;
/**
* 创建一个有size个数据的数值属性集合
*
* @param size
* 数据的个数
*/
public IntNumberPropertyArray(int size) {
values = new int[size];
bitSet = new BitSet(size);
}
public IntNumberPropertyArray(IntNumberPropertyArray set) {
values = new int[set.size()];
bitSet = new BitSet(values.length);
System.arraycopy(set.values, 0, values, 0, values.length);
this.bitSet.set(0, values.length, true);
}
/**
* 从指定的数值对象src拷贝数据到本实例
*
* @param src
* 数据的来源
*/
public void copyFrom(IntNumberPropertyArray src) {
System.arraycopy(src.values, 0, values, 0, values.length);
this.bitSet.set(0, values.length, true);
}
/**
* 设置index对应的值为value
*
* @param index
* @param value
* @return 返回值是是否确实被修改 true,修改;false,未修改
* @throws ArrayIndexOutOfBoundsException
* 如果index<0 或者 index>=size时会抛出此异常
*/
public boolean set(int index, int value) {
int _o = values[index];
if (_o != value) {
values[index] = value;
bitSet.set(index);
return true;
}
return false;
}
/**
* 取得index对应的int值
*
* @param index
* @return
* @throws ArrayIndexOutOfBoundsException
* 如果index<0 或者 index>=size时会抛出此异常
*/
public int get(int index) {
return values[index];
}
/**
* 增加index对应的int值
*
* @param index
* 属性的索引
* @param value
* 将要增加的值
* @return 增加后的值
*/
public int add(int index, int value) {
int _o = values[index];
int _n = _o + value;
if (_o != _n) {
values[index] = _n;
bitSet.set(index);
}
return values[index];
}
/**
* 是否有修改
*
* @return
*/
public boolean isChanged() {
return !this.bitSet.isEmpty();
}
/**
* 判定指定位是否修改
*
* @param index
* @return
*/
public boolean isChanged(int index){
return this.bitSet.get(index);
}
/**
* 重置修改,将所有的修改标识清空
*/
public void resetChanged() {
this.bitSet.clear();
}
/**
* 取得被修改过的的属性索引:优化修改过的索引及值,返回统一的Object
*
* @return
*/
public Object[] getChanged() {
int[] _indexes = new int[bitSet.cardinality()];
int[] _values = new int[bitSet.cardinality()];
Object[] changed = new Object[2];
changed[0] = _indexes;
changed[1] = _values;
for (int i = bitSet.nextSetBit(0), j = 0; i >= 0; i = bitSet.nextSetBit(i + 1), j++) {
_indexes[j] = i;
_values[j] = this.values[i];
}
return changed;
}
/**
* 取得属性的个数
*
* @return
*/
public int size() {
return this.values.length;
}
/**
* 清空状态,将values重置为0;把bitSet同时重置
*/
public void clear() {
for (int i = 0; i < values.length; i++) {
values[i] = 0;
}
this.bitSet.clear();
}
/**
* 计算该数据对象的所有数值的和
*
* @return
*/
public int sum() {
int _sum = 0;
for (int i = 0; i < this.values.length; i++) {
_sum += this.values[i];
}
return _sum;
}
/**
* 计算由指定的索引数组标识的属性数值的和
*
* @param indexs
* 被计算的属性的索引数组
* @return
*/
public int sum(int[] indexs) {
int _sum = 0;
for (int i = 0; i < indexs.length; i++) {
_sum += this.values[indexs[i]];
}
return _sum;
}
/**
* 计算除了指定的索引数组标识的以外的属性数值的和
*
* @param exceptIndexs
* 被排除的属性的索引数组
* @return
*/
public int sumExcept(final int[] exceptIndexs) {
int _sum = 0;
for (int i = 0; i < values.length; i++) {
_sum += this.values[i];
}
for (int i = 0; i < exceptIndexs.length; i++) {
_sum -= this.values[exceptIndexs[i]];
}
return _sum;
}
public String toString() {
return StringUtils.obj2String(this, null);
}
@Override
public IntNumberPropertyArray clone() {
IntNumberPropertyArray newGuy = new IntNumberPropertyArray(this);
return newGuy;
}
public KeyValuePair<Integer, Integer>[] getIndexValuePairs() {
KeyValuePair<Integer, Integer>[] indexValuePairs = KeyValuePair.newKeyValuePairArray(values.length);
for (int i = 0; i < indexValuePairs.length; i++) {
indexValuePairs[i] = new KeyValuePair<Integer, Integer>(Integer
.valueOf(i), values[i]);
}
return indexValuePairs;
}
}