Java数组排序(我做错了什么)

时间:2017-02-16 13:19:29

标签: java arrays sorting indexoutofboundsexception

编辑3:这是问题的原因:

对于removeArrayElement(第一个版本),它返回toArray(new Item [0]),它在结尾处执行null元素,但是使用new方法,它返回到不执行null的Array(arr),但是你可以创建一个T的泛型类型数组,即新的T [0],那么什么是替代?而不是再次传递数组'去除最后的null元素

老问题:

我最近更新了如何通过创建一个主方法来处理数组排序(通过implements泛型类型)只有aftermath方法才能给出数组超出边界的错误。

我有什么遗漏的吗?

旧方法:

private static Item[] insertTabItem(Item[] a, int pos, Item item) {
    Item[] result = new Item[a.length + 1];
    for(int i = 0; i < pos; i++)
        result[i] = a[i];
    result[pos] = item;
    for(int i = pos + 1; i < a.length + 1; i++)
        result[i] = a[i - 1];
    return result;
}

private static Item[] removeArrayItem(Item[] arr, Item item) {
   List<Item> list = new ArrayList<Item>(Arrays.asList(arr));
      for (int i = 0; i < list.size(); i++) {
          if (list.get(i) == item) {
              list.remove(i);
          }
      }
     return list.toArray(new Item[0]);
}

新方法(给出java.lang.ArrayIndexOutOfBoundsException)

public static <T> T[] insertArrayElement(T[] arr, int pos, T item) {
     final int N = arr.length;
    T[] result = Arrays.copyOf(arr, N + 1);
    for(int i = 0; i < pos; i++)
        result[i] = arr[i];
    result[pos] = item;
    for(int i = pos + 1; i < N + 1; i++)
        result[i] = arr[i - 1];
    return result;
}

public static <T> T[] removeArrayElement(T[] arr, T item) {
   List<T> list = new ArrayList<T>(Arrays.asList(arr));
      for (int i = 0; i < list.size(); i++) {
          if (list.get(i) == item) {
              list.remove(i);
          }
      }
     return list.toArray(arr);
}

编辑:

在阅读完一些答案后,我已将removeArrayElement更改为:

public static <T> T[] removeArrayElement(T[] arr, T item) {
   for (Iterator<T> iterator = list.iterator(); iterator.hasNext();) {
       T t = iterator.next();
        if (t == item) {
            iterator.remove();
        }
    }
     return list.toArray(arr);
}

但它仍然由于某种原因发送:java.lang.ArrayIndexOutOfBoundsException

EDIT2:完整的可执行文件

bankContents[bankSlots[0]] = Utils.removeArrayElement(bankContents[bankSlots[0]], newbankVarient);

当newBankVarient = bankContents [bankSlots [0]] [1]并删除它时,系统out of of array AFTER是:

"[var, var, var, null]

4 个答案:

答案 0 :(得分:1)

如果不运行代码,removeArrayElement可能会导致异常。

在迭代同一循环的list.remove(i)循环中使用for是不好的做法。

或者,您需要在break;调用后直接remove(i),或者您可以考虑使用迭代器,这样可以在迭代时安全删除&#34;。

例如:Java, Using Iterator to search an ArrayList and delete matching objects

最后,如果T具有可比性,那么您应该可以通过list.remove(item)从列表中删除 - 如果您不需要,则不需要乱用索引。

答案 1 :(得分:0)

正如@vikingsteve提到的那样,不要在循环中使用remove方法,因为你最有可能跳过可能的索引。

但是,你可以保持循环并从后面而不是从前面开始循环。

这样的事情可以做到:

<?php
 $MasterServer = "SomeIP1";
 $MasterServer2 = "SomeIP2";
 $MasterServer3 = "SomeIP3";

 echo "1 Server = ".$MasterServer;
 echo "2 Server = ".$MasterServer2;
 echo "3 Server = ".$MasterServer3;
?>

答案 2 :(得分:0)

在循环中删除是问题。当删除一个项目或使用基于迭代器的循环并调用iterator.remove时,问题减少i(i - )

答案 3 :(得分:0)

对于您的编辑3,这是javadoc

中描述的正确行为
  

如果列表适合指定的数组,并且有空余空间(即数组)   有比列表更多的元素),数组中的元素立即生效   在列表末尾之后设置为null。 (这在确定时很有用   仅当调用者知道列表不知道时,列表的长度   包含任何null元素。)

使用数组的空副本保留类型

private static Item[] removeArrayItem(Item[] arr, Item item) {
    Item[] emptyArray = Arrays.copyOf(arr, 0);
    List<Item> list = new ArrayList<Item>(Arrays.asList(arr));
    for (Iterator<Item> iter = list.iterator(); iter.hasNext();) {
      Item current = iter.next();
      if (item.equals(current)) {
        iter.remove();
        break;
      }
    }
    return list.toArray(emptyArray);
}
顺便说一句,对参考的平等测试是一个糟糕的实践,当你可以的时候更喜欢平等。 也许您也可以,如果您的项目具有可比性,请使用Arrays.binarySearch获取要删除的项目的索引,避免使用迭代器,而不是直接使用列表中的删除(索引)。