上节说道,多顶点形状的每一种属性都以属性流AttributeStream的形式保存,今天就来看一下AttributeStream是如何实现对属性的控制的(以double类型的数组AttributeStreamOfDbl为例)。
对数组的控制主要靠两点:
数组的长度:private int m_size;
和数组的内容:private double[] m_buffer = null;
从这两点我们吧AttributeStream的基础操作分为两类:对长度的控制和对内容的修改。
1.控制长度
函数名 | 功能 | 描述 | 核心 |
reserve | 控制数组长度 | 通过输入长度使数组处于最长状态 | System.arraycopy(m_buffer, 0, buf, 0, m_size); |
capacity | 获取数组长度 | 简单读取长度 | m_buffer.length |
resize | 控制数组长度 | 控制数组长度,在修改操作前几乎都要使用 | 新值小时改动小于25%修改buffer,否则不改; 新值大时 1.大于64位膨胀25%; 2.小于64膨胀两倍。 |
2.控制内容
函数名 | 功能 | 描述 | 核心 |
read | 简单读一条 | 简单读一条 | m_buffer[offset] |
write | 简单覆盖一条 | 简单覆盖一条 | m_buffer[offset] = value; |
add | 简单加一条 | 简单加一条,使用前用resize调整长度 | m_buffer[m_size - 1] = v; |
readAsInt... | read+强转 | read+强转 | (int) read(offset) |
writeAsInt | write+强转 | write+强转 | write(offset, (double) d); |
3.复杂一点的操作
函数名 | 功能 | 描述 | 核心 |
AttributeStreamOfDbl | 初始化 | 使用长度、长度+默认值、其他属性流、其他属性流+长度限制 做初始化 | 先初始化长度,再添加内容 System.arraycopy(); Arrays.fill(m_buffer, 0, size, defaultValue); other.m_buffer.clone(); |
equals | 判断相等 | 1.强转格式一致; 2.长度一致且不超限; 3.内容一致。 | |
addRange | 后加 | 1.调整大小resize; 2.复制数组arraycopy。 | |
insertRange | 中插 | 1.调整大小resize; 2.后 = 中; 3.中 = 新。 | |
insertAttributes | 语义中插 | 中插*语义包含属性数 | |
eraseRange | 删除 | 后 = 中 (后没删) | |
readRange | 正常读。。。 |
总结一下本节给我们控制数组的教训:
1.给长度以充分的重视,要给它写一全套的增、改、查、置零的方法,写的要简单易于执行。这里的长度控制函数超级朴实:resize(int newSize)给它一个长度让它内部给你分配操作。以后写类似程序时值得学习。
2.每次对内容进行改动时先要调用长度函数。
3.给数组预留的空间。还是指resize(int newSize)函数预留的策略,可以有效对数组操作,也可以提高运行速度用一定的空间复杂换取时间复杂。
附resize的程序:
public void resize(int newSize) {
if (m_bLockedInSize)
throw new GeometryException(
"invalid call. Attribute Stream is locked and cannot be resized.");
if (newSize <= m_size) {
if ((newSize * 5) / 4 < m_buffer.length) {// decrease when the 25%
// margin is exceeded
double[] newBuffer = new double[newSize];
System.arraycopy(m_buffer, 0, newBuffer, 0, newSize);
m_buffer = newBuffer;
}
m_size = newSize;
} else {
if (newSize > m_buffer.length) {
int sz = (newSize < 64) ? Math.max(newSize * 2, 4)
: (newSize * 5) / 4;
double[] newBuffer = new double[sz];
System.arraycopy(m_buffer, 0, newBuffer, 0, m_size);
m_buffer = newBuffer;
}
m_size = newSize;
}
}