【问题标题】:Remove Null Value from String array in java从java中的字符串数组中删除空值
【发布时间】:2011-05-08 04:56:36
【问题描述】:

如何从java中的String数组中删除空值?

String[] firstArray = {"test1","","test2","test4",""};

我需要像这样没有 null(空)值的“firstArray”

String[] firstArray = {"test1","test2","test4"};

【问题讨论】:

  • null 与 Java 中的“空字符串”完全不同。这是你的第一个问题。
  • null 不是 ""。 "" 是一个空但完全有效的字符串。
  • 该数组中没有空值。但是,有一个空字符串(长度为 0 的非空字符串对象)。不管怎样,什么你试过了吗?
  • 是的,你是对的。 null 与“”不同。只是我想删除所有空字符串,并且应该得到另一个没有空字符串的“字符串数组”。
  • 那么您可能需要更新您的问题以反映您的意思是空字符串而不是 null 的事实。

标签: java arrays string


【解决方案1】:

如果您想避免 fencepost 错误并避免移动和删除数组中的项目,这里有一个使用 List 的有点冗长的解决方案:

import java.util.ArrayList;
import java.util.List;

public class RemoveNullValue {
  public static void main( String args[] ) {
    String[] firstArray = {"test1", "", "test2", "test4", "", null};

    List<String> list = new ArrayList<String>();

    for(String s : firstArray) {
       if(s != null && s.length() > 0) {
          list.add(s);
       }
    }

    firstArray = list.toArray(new String[list.size()]);
  }
}

添加了 null 以显示空字符串实例 ("") 和 null 之间的区别。

由于这个答案大约有 4.5 年的历史,我正在添加一个 Java 8 示例:

import java.util.Arrays;
import java.util.stream.Collectors;

public class RemoveNullValue {
    public static void main( String args[] ) {
        String[] firstArray = {"test1", "", "test2", "test4", "", null};

        firstArray = Arrays.stream(firstArray)
                     .filter(s -> (s != null && s.length() > 0))
                     .toArray(String[]::new);    

    }
}

【讨论】:

    【解决方案2】:

    如果您确实想在数组中添加/删除项目,我可以建议使用List 代替吗?

    String[] firstArray = {"test1","","test2","test4",""};
    ArrayList<String> list = new ArrayList<String>();
    for (String s : firstArray)
        if (!s.equals(""))
            list.add(s);
    

    那么,如果你真的需要把它放回数组中:

    firstArray = list.toArray(new String[list.size()]);
    

    【讨论】:

    • 哈哈。你实现了我所描述的! :-) 我的一项改进是将new String[0] 传递给toArray,尽管它会根据需要创建一个具有正确大小的新数组。
    • 你应该使用String.isEmpty()而不是String.equals("")
    • @Steve,很多人都和你一样。我只是(个人)认为s.equals("") 更具可读性——不那么抽象。
    • @DaveJarvis,不言而喻,OP 将空字符串与 null 混淆了。
    • 你说得对,柯克。然而,NullPointerException 的可能性仍然存在。这是一个错误。
    【解决方案3】:

    似乎没有人提到过使用nonNull 方法,该方法也可以与 Java 8 中的streams 一起使用来删除 null(但不是空):

    String[] origArray = {"Apple", "", "Cat", "Dog", "", null};
    String[] cleanedArray = Arrays.stream(firstArray).filter(Objects::nonNull).toArray(String[]::new);
    System.out.println(Arrays.toString(origArray));
    System.out.println(Arrays.toString(cleanedArray));
    

    输出是:

    [Apple, , Cat, Dog, , null]

    [苹果, , 猫, 狗, ]

    如果我们也想合并空,那么我们可以定义一个实用方法(在类 Utils(say) 中):

    public static boolean isEmpty(String string) {
            return (string != null && string.isEmpty());
        }
    

    然后用它来过滤项目为:

    Arrays.stream(firstArray).filter(Utils::isEmpty).toArray(String[]::new);
    

    相信Apache common也提供了一个实用方法StringUtils.isNotEmpty也可以使用。

    【讨论】:

      【解决方案4】:

      使用谷歌的guava library

      String[] firstArray = {"test1","","test2","test4","",null};
      
      Iterable<String> st=Iterables.filter(Arrays.asList(firstArray),new Predicate<String>() {
          @Override
          public boolean apply(String arg0) {
              if(arg0==null) //avoid null strings 
                  return false;
              if(arg0.length()==0) //avoid empty strings 
                  return false;
              return true; // else true
          }
      });
      

      【讨论】:

      • 按照同样的方法,可以使用 FunctionalJava 库。
      • @Emil 然后,如何将st 中的内容放回firstArray 中?
      • @Abdull:没有必要这样做,因为 firstArray 没有被修改。过滤发生是惰性的。即在迭代数组时。
      • if(Strings.isNullOrEmpty(str)) 返回 false;可以用来代替 if(arg0==null) //避免空字符串返回 false; if(arg0.length()==0) //避免空字符串返回false;
      【解决方案5】:

      这是我用来从不使用数组列表的数组中删除空值的代码。

      String[] array = {"abc", "def", null, "g", null}; // Your array
      String[] refinedArray = new String[array.length]; // A temporary placeholder array
      int count = -1;
      for(String s : array) {
          if(s != null) { // Skips over null values. Add "|| "".equals(s)" if you want to exclude empty strings
              refinedArray[++count] = s; // Increments count and sets a value in the refined array
          }
      }
      
      // Returns an array with the same data but refits it to a new length
      array = Arrays.copyOf(refinedArray, count + 1);
      

      【讨论】:

      • 最后一行有一个错误。应该是count + 1
      【解决方案6】:

      一段 gc 友好的代码:

      public static<X> X[] arrayOfNotNull(X[] array) {
          for (int p=0, N=array.length; p<N; ++p) {
              if (array[p] == null) {
                  int m=p; for (int i=p+1; i<N; ++i) if (array[i]!=null) ++m;
                  X[] res = Arrays.copyOf(array, m);
                  for (int i=p+1; i<N; ++i) if (array[i]!=null) res[p++] = array[i];
                  return res;
              }
          }
          return array;
      }
      

      如果它不包含空值,它将返回原始数组。它不会修改原始数组。

      【讨论】:

        【解决方案7】:

        与上面已经发布的非常相似的批准。但是它更容易阅读。

        /**
         * Remove all empty spaces from array a string array
         * @param arr array
         * @return array without ""
         */
        public static String[] removeAllEmpty(String[] arr) {
            if (arr == null)
                return arr;
        
            String[] result = new String[arr.length];
            int amountOfValidStrings = 0;
        
            for (int i = 0; i < arr.length; i++) {
                if (!arr[i].equals(""))
                    result[amountOfValidStrings++] = arr[i];
            }
        
            result = Arrays.copyOf(result, amountOfValidStrings);
        
            return result;
        }
        

        【讨论】:

        • 它可能是可读的。但是代码看起来有点冗长。
        【解决方案8】:

        那些是零长度的字符串,不是空的。但如果你想删除它们:

        firstArray[0] refers to the first element
        firstArray[1] refers to the second element
        

        您可以将第二个移入第一个:

        firstArray[0]  = firstArray[1]
        

        如果您要对元素 [1,2]、[2,3] 等执行此操作,您最终会将数组的整个内容向左移动,从而消除元素 0。您知道这样做会如何申请?

        【讨论】:

        • 那么问题就变成了:“如何在 Java 中调整数组的大小”? :-)
        • 这并没有真正做到他想要的。这只是复制数据。它不会做任何事情来使数组更小。
        • 谢谢。但是如果我知道空的位置,我可以按照你说的做。但是动态生成的空字符串。我无法预测空(零长度)会出现在哪个位置。
        • 是的,但是s.size() == 0 会告诉你一个字符串是零长度的。这个想法是让您在零长度元素上迭代数组移位元素。这个问题太微不足道了,我认为这是家庭作业,不想给你完整的答案,但显然这就是被投票的原因。 耸耸肩
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-05
        • 2019-05-21
        • 2015-07-18
        • 2017-11-29
        • 1970-01-01
        • 1970-01-01
        • 2018-04-12
        相关资源
        最近更新 更多