Reputation: 29806
I have a need to place null objects at the end of the List
. Here is a sample what I have done for this purpose:
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);
}
}
I am looking forward to a more efficient and intelligent way to do this. Is it possible to swap inside the actual list so that null node get placed at the end, so that I don't need the other two list(nullStrings, result) and extra iteration.
Sorting will not work for my case. This sample code I made just for testing purpose. Actually I have a different type of Object. Also Sorting will break the position.
Say I have this null, Obj2, Obj1
, if do anything like sorting it may happens Obj1, Obj2, null
. But I need Obj2, Obj1, null
.
Upvotes: 3
Views: 3165
Reputation: 1
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);
Output-: [BR64, gen, localhost, QWG, qaGh20_241, R124, R219, SW6505, SWG620, SWG620, SWG62_, SW_6505, sw0, swd_157, TaGh20, taGh20, zen, , , null, null]
Upvotes: 0
Reputation: 9599
Just move non-null elements to the front and fill the rest of the list with 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);
If you are using LinkedList
(or something not a RandomAccess
), you'll need 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);
}
Upvotes: 4
Reputation: 3207
You can sort it using Collections.sort
and a custom Comparator
.
Here the compare code:
@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;
}
Note that elements that have an equal value according to this Comparator
won't be re-ordered. From Collections.sort
:
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
Upvotes: 11
Reputation: 691755
The general strategy looks fine to me. I would bring the following changes:
Although making a copy of the list will use more memory, it could well be faster than changing the initial list, because removing elements needs to move all the subsequent elements each time. And sorting is N*log(N), whereas copying elements is O(N).
[EDIT 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;
}
Upvotes: 2
Reputation: 1658
Below code you can use
Remove all the null elements
int noOfNull =0 ,i=0;
for(; i< strings.size() ; i++)
{
if(strings.get(i) == null)
{
noOfNull++;
}
}
strings.removeAll(Collections.singleton(null));
Filling the array with null after the not null elements
for(i =strings.size(); i < strings.size()+noOfNull ; i++)
{
strings.add(null);
}
Upvotes: 1