在2D ArrayList中移动元素

时间:2014-11-22 21:51:24

标签: java sorting arraylist 2d jlabel

我有2D ArrayList,其中填充了元素(包含图像等的对象),因此2D数组已满。在调用删除函数后,我的数组看起来像左侧的图片;在右侧,您可以看到所需的结果。有人可以告诉我如何重新组织我的阵列,如图所示吗?

the desired result

这个想法是从下到上。如果我找到间隙(间隙意味着我将元素的背景分别设置为nullimageIcon设置为null)我会将其切换为前一个元素。因为我已经切换它,我必须为整个专栏做。问题是,当它们有2个或更多的间隙时,这个算法什么都不做。

    for (int i = 0; i < 10; i++) {

        for (int j = 7; j > 0; j--) {
            Item currentItem = this.elements.get(j).get(i).getItem();

            if (currentItem.getBack().getIcon() == null) {
                int count = j;

                while (count > 1) {
                    Position temp = this.elements.get(count).get(i);
                    Position zero = this.elements.get(count).get(i);
                    Position previous = this.elements.get(count - 1).get(i);
                    zero = previous;
                    previous = temp;

                    count--;

                }

            }
        }
    }

由于我的游戏板面板,阵列数据大小限制为10x8。数组中的项目无法区分,它们只有不同的背景(JLabel组件的类型)。这些物品必须从上到下摔倒&#34;。

PS:我正在创建一个Bejeweled的克隆

shot1

shot2

3 个答案:

答案 0 :(得分:0)

根据您在图片中显示的内容,您希望列的元素“掉到底部”?如果是这种情况,您应该使用常规2D数组而不是ArrayList,并为每个使用数组,并假设底部已编入索引0 - 为什么?因为ArrayList没有固定大小,并且您的问题语句显示您希望容器具有固定大小。然后解决方案是(粗略地,因为您只显示了代码的一部分,而不是SSCCE):

//Item[][] items;
for( Item[] arr : items )
  for( int i = arr.length - 2; i >= 0; i-- )
    if ( arr[i] == null ) // or arr[i].getBack().getIcon() == null or whatever
      for( int j = i; j < arr.length - 1; j++ )
        arr[j] = arr[j+1];

这是一种粗略的冒泡排序,适用于小型阵列。还有其他可能的解决方案(因为这本身就是一个排序问题 - 你可能会查询qsort),但这个可以说是最简单的。

注意:您可以为ArrayList实现完全相同的解决方案,但我强烈反对它。使用嵌套的ArrayList来模拟多维数组很少是一个好主意 - 无论如何它都会创建数组,但是你会得到很大的开销,使代码变慢和不易读 - 无论如何你可以做所以将[]替换为get() / set()

为了参考:

//ArrayList<ArrayList<Item>> items;
//int columnHeight;
for( ArrayList<Item> arr : items )
  for( int i = columnHeight - 2; i >= 0; i-- )
    if ( arr.get(i) == null ) //or arr.get(i).getIcon()==null or whatever
      for( int j = i; j < columnHeight - 1; j++ )
        arr.set(j, arr.get(j+1));

或简单地说,通过提供比较器:

//ArrayList<ArrayList<Item>> items;
//int columnHeight;
for( ArrayList<Item> arr : items )
  Collections.sort(arr, new Comparator<Item>() {
    @Override
    public int compare(Item i1, Item i2) {
        return ...; // place the sorting rule here
    }
  });

有关详细信息,请参阅Collections.sort()&amp;的文档。 Comparator

此外,如果这确实适用于宝石迷阵克隆 - 您可以考虑通过迭代将所有珠宝下方的空白字段向下移动一步来计算“丢弃”,计算丢弃的珠宝数量,并重复这个迭代,直到滴数== 0.这就是我过去几天在克隆中使用的算法。

答案 1 :(得分:-1)

正如@vaxquis已经提到过的,以更优雅的方式重写代码会更好。

for (int i = 0; i < 10; i++) {

    // Perfoming bubble sort for each column
    boolean swapped = true;
    for(int j = 6; j > 0 && swapped; j--) {
        swapped = false;

        for (int k = 0; k < j; k++) {
            Item currentItem =  this.elements.get(k).get(i).getItem();
            Item nextItem    =  this.elements.get(k+1).get(i).getItem();

            if (currentItem.getBack().getIcon() != nextItem.getBack().getIcon()) {
                swap(currentItem, nextItem);   // implement this yourself
                swapped = true;
            }

        }
    }
}

答案 2 :(得分:-1)

除了其他答案解决的算法问题之外,您的主要问题是您永远不会更改数组中的任何内容。以下代码只是在局部变量之间移动一些值:

Position temp = this.elements.get(count).get(i);
Position zero = this.elements.get(count).get(i);
Position previous = this.elements.get(count - 1).get(i);
zero = previous;
previous = temp;

您可能有一个setItem()方法将事物设置回Position对象?交换将是:

Position current = this.elements.get(count).get(i);
Position previous = this.elements.get(count - 1).get(i);
Item temp = current.getItem();
current.setItem(previous.getItem();
previous.setItem(temp);
相关问题