最近做的一个功能需要对 List 中的元素进行交换,最开始想到了用 Collections 中的 swap 方法,但后来发现 ECore 模型属性的 unique 是 true,那就肯定是不能用 swap 方法了,因为 Collections 中 swap 的实现使用了 List 的 set 方法
public static void swap(List<?> list, int i, int j) {
final List l = list;
l.set(i, l.set(j, l.get(i)));
}
而 BasicEList 为了保证 unique 为 true 时列表中元素的唯一性,在 set 方法中做了如下处理
if (isUnique()) {
int currentIndex = indexOf(object);
if (currentIndex >= 0 && currentIndex != index) {
throw new IllegalArgumentException("The 'no duplicates' constraint is violated");
}
}
从上面的代码中可以看出,在 isUnique 返回 true 时,在 EList 的实现类 BasicEList 中,限制了同一对象实例多次出现在 List 中的可能。
那么我们如何才能够在 EList 中完成元素位置的交换呢?其实在 EList 接口中定义了两个 move 方法:
/**
* Moves the object to the new position, if is in the list.
* @param newPosition the position of the object after the move.
* @param object the object to move.
*/
void move(int newPosition, Object object);
/**
* Moves the object from the old position to the new position.
* @param newPosition the position of the object after the move.
* @param oldPosition the position of the object before the move.
* @return the moved object.
*/
Object move(int newPosition, int oldPosition);
使用起来很简单:
list.move(newPosition, oldPosition);
接下来我们看看 move 是如何实现的:
public Object move(int targetIndex, int sourceIndex) {
++modCount;
if ( targetIndex >= size )
throw new IndexOutOfBoundsException("targetIndex=" + targetIndex
+ ", size=" + size);
if ( sourceIndex >= size )
throw new IndexOutOfBoundsException("sourceIndex=" + sourceIndex
+ ", size=" + size);
Object object = data[sourceIndex];
if ( targetIndex != sourceIndex ) {
if ( targetIndex < sourceIndex ) {
System.arraycopy(data, targetIndex, data, targetIndex + 1,
sourceIndex - targetIndex);
} else {
System.arraycopy(data, sourceIndex + 1, data, sourceIndex,
targetIndex - sourceIndex);
}
assign(targetIndex, object);
didMove(targetIndex, object, sourceIndex);
didChange();
}
return object;
}
代码很清晰,arraycopy 和 assign 完成了元素位置的交换。
posted on 2010-01-05 15:52
都市鸟人 阅读(380)
评论(0) 编辑 收藏 所属分类:
Eclipse 、
EMF