在List的末尾放置null

时间:2013-07-20 12:05:52

标签: java list collections null

我需要在List的末尾放置空对象。以下是我为此目的所做的一个示例:

public static void main(String... args) {
    List<String> strings = Arrays.asList(new String[]{"A", null, "B"});

    for(String string : strings) {
        System.out.println(string);
    }

    System.out.println("==================");

    List<String> result = new ArrayList<String>();
    List<String> nullStrings = new ArrayList<String>();

    for(String string : strings) {
        if(string != null) {
            result.add(string);         
        } else {
            nullStrings.add(string);
        }
    }

    result.addAll(nullStrings);

    for(String string : result) {
        System.out.println(string);
    }
}

我期待以更高效,更智能的方式做到这一点。是否可以在实际列表中进行交换,以便将null节点放在最后,这样我就不需要另外两个列表(nullStrings,result)和额外的迭代。

更新

排序对我的情况不起作用。我的示例代码仅用于测试目的。实际上我有一个不同类型的对象。排序也会打破这个位置。

假设我有null, Obj2, Obj1,如果做了排序,可能会发生Obj1, Obj2, null。但我需要Obj2, Obj1, null

5 个答案:

答案 0 :(得分:10)

您可以使用Collections.sort和自定义Comparator对其进行排序。

这里是比较代码:

@Override 
public int compare(String left, String right) {
 if (left == right) {
   return 0;
 }
 if (left == null) {
   return 1;
 }
 if (right == null) {
   return -1;
 }
 return 0;
 }

请注意,根据此Comparator具有相同值的元素将不会重新排序。来自Collections.sort

  

这种保证是稳定的:相同的元素不会因排序而重新排序。

答案 1 :(得分:4)

只需将非null元素移到前面,然后用null填充列表的其余部分。

int j = 0;
for (int i = 0; i < strings.size(); i++)
    if (strings.get(i) != null){
        strings.set(j, strings.get(i));
        j++;
    }
for (; j < strings.size(); j++)
    strings.set(j, null);

如果您使用的是LinkedList(或某些不是RandomAccess),则需要ListIterator

ListIterator<String> j = strings.listIterator();
for (ListIterator<String> i = strings.listIterator(); i.hasNext();) {
    String s = i.next();
    if (s != null) {
        j.next();
        j.set(s);
    }
}
while (j.hasNext()) {
    j.next();
    j.set(null);
}

答案 2 :(得分:2)

一般策略对我来说很好。我会带来以下变化:

  • 使用适当的大小初始化结果列表
  • 不要使用单独的空列表。在迭代结束时,您只需要将初始列表的长度与结果列表的长度进行比较,以了解需要添加多少空值。

尽管制作列表的副本将使用更多内存,但它可能比更改初始列表更快,因为删除元素需要每次都移动所有后续元素。排序是N * log(N),而复制元素是O(N)。

[编辑owlstead]

public static List<String> moveNullsToEnd(final List<String> strings) {

    final List<String> newStrings = new ArrayList<String>(strings.size());

    for (String string : strings) {
        if (string != null) {
            newStrings.add(string);
        }
    }

    for (int i = 0, remaining = strings.size() - newStrings.size(); i < remaining; i++) {
        newStrings.add(null);
    }

    return newStrings;
}

答案 3 :(得分:1)

下面的代码可以使用

删除所有空元素

int noOfNull =0 ,i=0;

for(; i< strings.size() ; i++)
{
    if(strings.get(i) == null)
    {
        noOfNull++;
    }
}
strings.removeAll(Collections.singleton(null));

在非null元素

之后用null填充数组
for(i =strings.size(); i < strings.size()+noOfNull ; i++)
        {
            strings.add(null);
        }

答案 4 :(得分:0)

List<String> list = new ArrayList<>();
list.add("BR64");
list.add("SWG620");
list.add("");
list.add("sw0");
list.add("R124");
list.add("R219");
list.add("TaGh20");
list.add("SW6505");
list.add("");
list.add(null);
list.add("SW_6505");
list.add("swd_157");
list.add("localhost");
list.add("qaGh20_241");
list.add("gen");
list.add(null);
list.add("taGh20");
list.add("zen");
list.add("QWG");
list.add("SWG62_");
list.add("SWG620");


Collections.sort(list, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        if (o1 != null && o2 != null && o1.length() > 0 && o2.length() > 0) {
            return (Character.toLowerCase(o1.charAt(0)) == Character.toLowerCase(o2.charAt(0)))
                    ? o1.compareTo(o2)
                    : (Character.toLowerCase(o1.charAt(0)) + o1.substring(1))
                            .compareTo((Character.toLowerCase(o2.charAt(0)) + o2.substring(1)));
        } else {
            return (o1 == o2) ? 0 : ((o1 == null || o1 == "") ? 1 : -1);
        }
    }
});
System.out.println(list);

输出-:[BR64,gen,localhost,QWG,qaGh20_241,R124,R219,SW6505,SWG620,SWG620,SWG62_,SW_6505,sw0,swd_157,TaGh20,taGh20,zen 、、 null,null,null]