我正在使用Swing的应用程序。我有一个JTabbedPane,每个标签都被视为“页面”。每个页面包含4个普通面板(我将它们称为“视图”),这些面板按照2x2 GridLayout排列。
我想最小化页面数量,所以每次删除一个视图时,我都希望对所有页面中的所有视图进行重新排序(如果它更有意义,可以考虑二维数组),以便最后一页附近的视图并从那里删除,并被添加到靠近前面的页面。
考虑这个例子:
Object[][] array = new Object [][] {
{ new Object(), null, new Object(), new Object() },
{ null, null, new Object(), new Object() },
{ new Object(), new Object(), new Object(), new Object() }
};
如何对该数组进行排序,使其看起来更像:
Object[][] array = new Object[][] {
{ new Object(), new Object(), new Object(), new Object() },
{ new Object(), new Object(), new Object(), new Object() },
{ new Object(), null, null, null },
};
起初,我想过使用两个循环,一个从0到array.length
,一个从array.length
变为0.这个想法是:当一个从长度变为0接近0,它将检查从 0到长度的数组的索引是否为空。如果是这样,它会将非null元素放在包含null
的索引中。
这种方法让我头疼,因为所有的循环所以我问了我的一位好朋友的建议。他提出了一个更优雅的解决方案:Arrays.sort(Object[][], Comparator)
。
此代码是结果:
Object[][] array = new Object[][] { { new Object(), null, new Object(), new Object() }, { null, null, new Object(), new Object() }, { new Object(), new Object(), new Object(), new Object() } };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
System.out.println("Before sorting: (i = " + i + " j = " + j + " null = " + (array[i][j] == null) + ")");
}
}
Arrays.sort(array, new Comparator<Object>()
{
public int compare(Object a, Object b)
{
return a == null ? (b == null ? 0 : -1) : (b == null ? 1 : 0);
}
});
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
System.out.println("After sorting: (i = " + i + " j = " + j + " null = " + (array[i][j] == null) + ")");
}
}
输出结果为:
Before sorting: (i = 0 j = 0 null = false) Before sorting: (i = 0 j = 1 null = true) Before sorting: (i = 0 j = 2 null = false) Before sorting: (i = 0 j = 3 null = false) Before sorting: (i = 1 j = 0 null = true) Before sorting: (i = 1 j = 1 null = true) Before sorting: (i = 1 j = 2 null = false) Before sorting: (i = 1 j = 3 null = false) Before sorting: (i = 2 j = 0 null = false) Before sorting: (i = 2 j = 1 null = false) Before sorting: (i = 2 j = 2 null = false) Before sorting: (i = 2 j = 3 null = false) After sorting: (i = 0 j = 0 null = false) After sorting: (i = 0 j = 1 null = true) After sorting: (i = 0 j = 2 null = false) After sorting: (i = 0 j = 3 null = false) After sorting: (i = 1 j = 0 null = true) After sorting: (i = 1 j = 1 null = true) After sorting: (i = 1 j = 2 null = false) After sorting: (i = 1 j = 3 null = false) After sorting: (i = 2 j = 0 null = false) After sorting: (i = 2 j = 1 null = false) After sorting: (i = 2 j = 2 null = false) After sorting: (i = 2 j = 3 null = false)
完全一样。
我还尝试将compare(Object, Object)
实现替换为:
public int compare(Object a, Object b)
{
if (a == null && b != null)
{
return -1;
}
if (b == null && a != null)
{
return 1;
}
return 0;
}
......并取得了相同的成果。 我有点不知所措。这不是我不知道要做的事情,我无法解决如何为这样的问题实际创建解决方案。
我很感激任何帮助。无论你喜欢接近它,循环方法还是比较方法,我都很乐意看到它!
谢谢!
答案 0 :(得分:2)
你的意思是
Object[][] array = new Object [][] { .. };
在您的情况下,您需要将二维数组转换为数组(一维数组)。排序新数组后,使用已排序的数组填充二维数组。
// convert to 1-D array
Object[] all = new Object[12];
int k = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
all[k++] = array[i][j];
}
}
// then sort the new array
Arrays.sort(all, yourComparator);
// then fill the 2-D array with the sorted array
k = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
array[i][j] = all[k++];
}
}
答案 1 :(得分:1)
数组的类型为Object[][]
。因此,当您执行sort(array, theComparator)
时,您正在安排Object[]
内保留的三个array
中的每一个。您不对这三个数组中的每一个的内容进行排序。
由于Object[]
中的三个array
都不为空,因此您的比较器会在每次比较时返回零,因此Object[]
保留在array
内。
因此,您需要转换为Object
的1-D数组,对其进行排序,然后将其分解为2-D数组。
答案 2 :(得分:1)
您的示例不清楚,显然与您的实际应用程序要求不符。 (对一堆无差别的Object
实例进行排序是没有意义的!)
所以我要采取刺...并猜测你真的只是想把空值移到最后。 (其他非null元素已经排序,删除一个/一些不会改变它。或者它们根本不需要排序......)
如果是这种情况,那么简单的方法就是这样做:
或者,如果您需要对非null元素进行排序,则可以使用Arrays.sort(Object[], int, int)
在1-D数组中进行排序。选择边界以排除数组末尾的空值。这避免了创建理解null
的“复杂”比较器的需要。
您当前的方法太复杂了......不必要的复杂代码是一个坏主意。
如果您的意图是在保留其他对象的顺序的同时将空值移动到最后,那么sort
是一种昂贵的方法。 (它将与您定义的Comparator
一起使用,因为sort(Object[] ...)
方法被记录为执行稳定排序。但在这种情况下,我很想说它是不幸< / em>它有效。)
答案 3 :(得分:0)
您的代码失败的原因是您只是检查外部数组是否为null,您还应该检查外部数组的内容。
请参阅此代码:
import java.util.Arrays;
import java.util.Comparator;
public class Test2DArrayComparator {
public static void main(String[] args) {
Object[][] array = new Object[][]{
{new Object(), null, new Object(), new Object()},
{null, null, new Object(), new Object()},
{new Object(), new Object(), new Object(), new Object()}
};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
System.out.println("Before sorting: (i = " + i + " j = " + j + " null = " + (array[i][j] == null) + ")");
}
}
class ArrayComparator implements Comparator<Object>{
@Override
public int compare(Object a, Object b) {
if(a == null && b == null){
return 0;
} else if(a != null && b == null){
return 1;
} else if(a == null && b != null){
return -1;
} else {
return checkConents(((Object[])a), ((Object[])b));
}
}
}
Arrays.sort(array, new ArrayComparator());
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
System.out.println("After sorting: (i = " + i + " j = " + j + " null = " + (array[i][j] == null) + ")");
}
}
}
static int checkConents(Object[] first, Object[] second){
for(int iDx = 0; iDx < first.length; iDx++){
if(first[iDx] != null && second[iDx] == null){
return -1;
} else if(first[iDx] == null && second[iDx] == null){
return 0;
} else if(first[iDx] == null && second[iDx] != null){
return 1;
}
}
return -1;
}
}
在检查外部数组checkContent
的有效性之后调用以比较内容,同时注意checkContent
假设两个数组的大小相同。
答案 4 :(得分:0)
您不希望代码中包含空值,您不希望检查null,您不想偶然发现null,并且您不希望null携带语义。
因此你不需要数组。
如果您想使用不同大小的Collection,请不要使用Arrays。
使用ArrayList,例如,易于使用,可变大小,无需使用空值。
如果从ArrayList中删除元素2:
List <JPanel> al = new ArrayList <JPanel> ();
al.add (new JPanel ());
al.add (new JPanel ());
al.add (new JPanel ());
al.add (new JPanel ());
al.remove (1); // 0-based numbering like in Arrays.
现在元素2和3将向前滑动一个位置。你的阵列现在多久了?
System.out.println (al.size ());
List中没有null,不需要对null进行测试,迭代?
for (JPanel jp : al)
// do something to every jp.
不要在代码中使用null,但禁止它!
不要将Arrays用于不同大小的集合!