我有一个用户给我一个随机的对象数组,我想做一些错误检查,基本上我希望null对象位于数组的末尾,这样数组的中间只是由一个组成非空对象(对象的排序无关紧要)。
这是我拥有的,它不起作用。 任何人都可以帮忙。
private void properArray(){
int i = 0;
int j;
int cap = theHeap.length;
for(; i < (cap-1); i++){
if (theHeap[i] == null){
j = i + 1;
while(j < (cap-1)){
if(theHeap[j] != null){
theHeap[i] = theHeap[j];
theHeap[j] = null;
}
j++;
}
}
}
}
答案 0 :(得分:8)
以下是一种更简单的方法,可以对这样的数组进行排序:
Arrays.sort(theHeap, new Comparator() {
public int compare(Object o1, Object o2) {
// nulls are "greater" than non-nulls
if (o1 == null && o2 != null) return 1;
// non-nulls are "smaller" than nulls
if (o1 != null && o2 == null) return -1;
// in all other comparisons, we don't care
return 0;
}
});
或者使用Java 8:
Arrays.sort(theHeap, (o1, o2) -> (o1 == null && o2 != null) ? 1
: (o1 != null && o2 == null) ? -1
: 0);
如果您的类路径中有Apache Commons Collections,则可以使用更少的代码编写此代码:
Arrays.sort(theHeap, new NullComparator());
正如Ted所提到的,这在O(n log n)
中执行并创建了一个用于排序的数组克隆......因此它不是最快的解决方案......
答案 1 :(得分:3)
没有必要在数组中迭代两次。如果您不关心非null对象的顺序(特别是,如果它们不需要保持相同的相对顺序),您可以非常简单地执行此操作:
int end = theHeap.length;
for (int i = 0; i < end; ++i) {
while (theHeap[i] == null && i < end) {
--end;
theHeap[i] = theHeap[end];
theHeap[end] = null;
}
}
由于每次循环迭代(外部或内部)将(end - i)
减少一个,并且循环在它们相遇时结束,这是一个O(N)算法。
编辑修改版本,避免交换空值(可能略微提高效率):
int end = theHeap.length;
for (int i = 0; i < end; ++i) {
if (theHeap[i] == null) {
while (--end > i && theHeap[end] == null) {
// loop
}
if (i < end) {
theHeap[i] = theHeap[end];
theHeap[end] = null;
}
}
}
EDIT 2 一个更简单的版本,它还维护非null元素的初始排序顺序:
int next = 0;
for (int i = 0; i < theHeap.length; ++i) {
if (theHeap[i] != null) {
if (i > next) {
theHeap[next] = theHeap[i];
theHeap[i] = null;
}
++next;
}
}
答案 2 :(得分:0)
尝试:
int j = array.length;
for (int i = 0; i < j; ++i) {
if (array[--j] == null) {
continue;
}
// array[j] is not null.
if (array[i] == null) {
array[i] = array[j];
array[j] = null;
}
}