Niranjan Kumar
Niranjan Kumar

Reputation: 869

In Java, remove empty elements from a list of Strings

In Java, I have an ArrayList of Strings like:

[,Hi, ,How,are,you]

I want to remove the null and empty elements, how to change it so it is like this:

[Hi,How,are,you]

Upvotes: 75

Views: 185265

Answers (14)

virendra khade
virendra khade

Reputation: 1

// Here i have posted two approaches, please go through it

private static void consumerExample() {
    List<String> list = Arrays.asList("Java", "\n \n", "Python", " ", null);
    System.out.println("==================== ");
    Consumer<List<String>> modify = list1 -> {
        for (int i = 0; i < list1.size(); i++)
            if (getOnlyStrings(list1.get(i)).length() > 0)
                System.out.println(list1.get(i));
    };
    modify.accept(list);
    System.out.println("====================");
}

public static String getOnlyStrings(String s) {
    String str = "";
    try {
        Pattern pattern = Pattern.compile("[^a-z A-Z]");
        if (s == null || s.trim().length() == 0)
            return "";
        Matcher matcher = pattern.matcher(s);
        str = matcher.replaceAll("");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return str;
}

public static void main(String[] args) {
    consumerExample();
    List<String> list = Arrays.asList("Java", "\n \n", "Python", " ", null);

    List<String> collection = new ArrayList<>(Arrays.asList("A", null, "B", null, "C", "", "D"));

    // collection.removeIf(s -> s == null || "".equals(s));

    // System.out.println(collection);

    list.stream().filter(p -> getOnlyStrings(p).length() > 0).forEach(System.out::println);
    ;
}

Upvotes: 0

tokhi
tokhi

Reputation: 21626

Its a very late answer, but you can also use the Collections.singleton:

List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));
// in one line
list.removeAll(Arrays.asList("", null))

// separately
list.removeAll(Collections.singleton(null));
list.removeAll(Collections.singleton(""));

Upvotes: 50

Woodchuck
Woodchuck

Reputation: 4474

lukastymo's answer seems the best one.

But it may be worth mentioning this approach as well for it's extensibility:

List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));

list = list.stream()
           .filter(item -> item != null && !item.isEmpty())
           .collect(Collectors.toList());

System.out.println(list);

What I mean by that (extensibility) is you could then add additional filters, such as:

          .filter(item -> !item.startsWith("a"))

... although of course that's not specifically relevant to the question.

Upvotes: 2

sandybarasker
sandybarasker

Reputation: 101

List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", "", "How"));
           Stream<String> stream = list .stream();
           Predicate<String> empty = empt->(empt.equals(""));
            Predicate<String> emptyRev = empty.negate();
           list=  stream.filter(emptyRev).collect(Collectors.toList());

OR

list =  list .stream().filter(empty->(!empty.equals(""))).collect(Collectors.toList());

Upvotes: 1

The Hunter
The Hunter

Reputation: 155

If you are using Java 8 then try this using lambda expression and org.apache.commons.lang.StringUtils, that will also clear null and blank values from array input

public static String[] cleanArray(String[] array) {
    return Arrays.stream(array).filter(x -> !StringUtils.isBlank(x)).toArray(String[]::new);
}

ref - https://stackoverflow.com/a/41935895/9696526

Upvotes: 9

AnT
AnT

Reputation: 891

If you get UnsupportedOperationException from using one of ther answer above and your List is created from Arrays.asList(), it is because you can't edit such List.

To fix, wrap the Arrays.asList() inside new LinkedList<String>():

    List<String> list = new LinkedList<String>(Arrays.asList(split));

Source is from this answer.

Upvotes: 3

Sam Berry
Sam Berry

Reputation: 7844

Going to drop this lil nugget in here:

Stream.of("", "Hi", null, "How", "are", "you")
  .filter(t -> !Strings.isNullOrEmpty(t))
  .collect(ImmutableList.toImmutableList());

I wish with all of my heart that Java had a filterNot.

Upvotes: 7

Asaf Blum
Asaf Blum

Reputation: 27

Regarding the comment of Andrew Mairose - Although a fine solution, I would just like to add that this solution will not work on fixed size lists.

You could attempt doing like so:

Arrays.asList(new String[]{"a", "b", null, "c", "    "})
    .removeIf(item -> item == null || "".equals(item));

But you'll encounter an UnsupportedOperationException at java.util.AbstractList.remove(since asList returns a non-resizable List).

A different solution might be this:

List<String> collect =
    Stream.of(new String[]{"a", "b", "c", null, ""})
        .filter(item -> item != null && !"".equals(item))
        .collect(Collectors.toList());

Which will produce a nice list of strings :-)

Upvotes: 2

user2982704
user2982704

Reputation: 159

   private List cleanInputs(String[] inputArray) {
        List<String> result = new ArrayList<String>(inputArray.length);
        for (String input : inputArray) {
            if (input != null) {
                String str = input.trim();
                if (!str.isEmpty()) {
                    result.add(str);
                }
            }
        }
        return result;
    }

Upvotes: 0

Andrew Mairose
Andrew Mairose

Reputation: 11005

Another way to do this now that we have Java 8 lambda expressions.

arrayList.removeIf(item -> item == null || "".equals(item));

Upvotes: 32

Stephen C
Stephen C

Reputation: 719679

There are a few approaches that you could use:

  1. Iterate over the list, calling Iterator.remove() for the list elements you want to remove. This is the simplest.

  2. Repeatedly call List.remove(Object). This is simple too, but performs worst of all ... because you repeatedly scan the entire list. (However, this might be an option for a mutable list whose iterator didn't support remove ... for some reason.)

  3. Create a new list, iterate over the old list, adding elements that you want to retain to a new list.

  4. If you can't return the new list, as 3. above and then clear the old list and use addAll to add the elements of the new list back to it.

Which of these is fastest depends on the class of the original list, its size, and the number of elements that need to be removed. Here are some of the factors:

  • For an ArrayList, each individual remove operation is O(N), where N is the list size. It is expensive to remove multiple elements from a large ArrayList using the Iterator.remove() method (or the ArrayList.remove(element) method).

    By contrast, the Iterator.remove method for a LinkedList is O(1).

  • For an ArrayList, creating and copying a list is O(N) and relatively cheap, especially if you can ensure that the destination list's capacity is large enough (but not too large).

    By contrast, creating and copying to a LinkedList is also O(N), but considerably more expensive.

All of this adds up to a fairly complicated decision tree. If the lists are small (say 10 or less elements) you can probably get away with any of the approaches above. If the lists could be large, you need to weigh up all of the issues in the list of the expected list size and expected number of removals. (Otherwise you might end up with quadratic performance.)

Upvotes: 5

lukastymo
lukastymo

Reputation: 26809

List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));
System.out.println(list);
list.removeAll(Arrays.asList("", null));
System.out.println(list);

Output:

[, Hi, null, How]
[Hi, How]

Upvotes: 105

no.good.at.coding
no.good.at.coding

Reputation: 20371

  1. If you were asking how to remove the empty strings, you can do it like this (where l is an ArrayList<String>) - this removes all null references and strings of length 0:

    Iterator<String> i = l.iterator();
    while (i.hasNext())
    {
        String s = i.next();
        if (s == null || s.isEmpty())
        {
            i.remove();
        }
    }
    
  2. Don't confuse an ArrayList with arrays, an ArrayList is a dynamic data-structure that resizes according to it's contents. If you use the code above, you don't have to do anything to get the result as you've described it -if your ArrayList was ["","Hi","","How","are","you"], after removing as above, it's going to be exactly what you need - ["Hi","How","are","you"].

    However, if you must have a 'sanitized' copy of the original list (while leaving the original as it is) and by 'store it back' you meant 'make a copy', then krmby's code in the other answer will serve you just fine.

Upvotes: 9

Kerem Baydoğan
Kerem Baydoğan

Reputation: 10720

  • This code compiles and runs smoothly.
  • It uses no iterator so more readable.
  • list is your collection.
  • result is filtered form (no null no empty).

public static void listRemove() {
    List<String> list = Arrays.asList("", "Hi", "", "How", "are", "you");
    List<String> result = new ArrayList<String>();

    for (String str : list) {
        if (str != null && !str.isEmpty()) {
            result.add(str);
        }
    }

    System.out.println(result);
}

Upvotes: 4

Related Questions