我有一个字符串数组列表,其中包含一些null
值和一些字符串。我不想对数组列表进行排序,但我应该对数组列表排序,使null值排在最后。假设arraylist是{1,2,null,6,5,null, 3}
,我应该在最后一个{1,2,6,5,3,null,null}
得到null值。
解决方案,我目前有:现在,我正在构建新的arraylist,如果值是null
,我不会将其推送到新列表中,否则我会将其添加到新的arraylist。
还有其他更好的解决方案吗?
谢谢你的帮助。
如果您使用Java 8,您可以轻松构建所需的比较器:
Arrays.sort(stringArray, Comparator.nullsLast(Comparator.naturalOrder()));
但如果你不使用java8,你可以有一个类似下面的比较器
public class StringNullComparator implements Comparator<String> {
public int compare(String stringOne, String stringTwo) {
if (stringOne != null && stringTwo != null)
return stringOne.compareTo(stringTwo);
return (stringOne == stringTwo)?0:(stringOne==null? 1 : -1);
}
}
你可以在下面的中使用
Arrays.sort(stringArray, new StringNullComparator());
要传递给排序的自定义比较器:
public class StringComparator implements Comparator<String> {
public int compare(String s1, String s2) {
if (s1 != null && s2 != null)
return s1.compareTo(s2);
return (s1 == null) ? 1 : -1;
}
}
然后:
Collectios.sort(list, new StringComparator());
如果您想避免在整个列表上显式迭代,可以使用ArrayList.indexOf()查找空值,然后移除()。如果你想保留列表中的值,你可以在列表的末尾添加一个null值。然而,如果这是一个问题,我认为这种方法在性能方面并不好。
您可以使用apache中的NullComparator。
Collections.sort(list, new NullComparator());
构造新的arraylist怎么样?如果它是实数,则将其添加到新列表中,如果它是空增量,则添加计数器。最后加上等于计数器值的null数。
如果你想把null排序到最后并保持非null元素的顺序,这个Comparator
会这样做:
class CompareStrings implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
if (o1 == null && o2 != null)
return 1;
if (o2 == null && o1 != null)
return -1;
return 0;
}
}
如果两个String
都为null或非null,则它们将比较为相等。如果只有一个为空,它将被比较为小于非空的一个。
怎么样:
class MyInteger implements Comparator<Integer> {
public int compare(Integer arg0, Integer arg1) {
if(arg1 == null) {
return -1;
}
return 0;
}
}
我们可以像这样使用它:
List<Integer> al = new ArrayList<Integer>();
al.add(1);
al.add(2);
al.add(null);
al.add(6);
al.add(5);
al.add(null);
al.add(3);
Collections.sort(al, new MyInteger());
所有其他解决方案都涉及排序。正如你提到的,你其实并不需要排序。如果时间复杂性是一个问题,您可以使用以下线性时间解决方案(就地):
public static <T> void nullsToEndInPlace(List<T> l) {
int i = 0;
int j = l.size() - 1;
while (i < j) {
T left = l.get(i);
T right = l.get(j);
if (left != null) {
i++;
} else if (right == null) {
j--;
} else {
l.set(i, right);
l.set(j, null);
i++;
j--;
}
}
}
试试这个。
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,SWG62_,SW_6505,sw0,swd_157,TaGh20,TaGh20,zen,,,null,null]
list.sort()
和sorted()
都有一个关键参数,用于指定在进行比较之前对每个列表元素调用的函数。
例如,这里有一个不区分大小写的字符串比较:
sorted("This is a test string from sohan".split(), key=str.lower)
['a', 'from', 'is', 'sohan', 'string', 'test', 'This']
这里,key=str.lower()
会将每个字符串转换为小写,然后对结果进行排序。
有关排序的更多信息,请单击此处