在Java中从字符串数组中删除未填充或空值

11
我有以下字符串数组: tmp = [null, null, null, Mars, Saturn, Mars] 是通过执行操作allSig[d3].split(" ");得到的,其中allSig是一个字符串数组。 空值在数组中表示为null。现在我想要去除这些空值。 为此,我正在使用tmp[indexNumber] != null ,但它却将null视为非空值并返回true; 即使我使用"null"作为字符串也不起作用。 如何解决此问题?
public static String[] removeElements(String[] allElements) {
    String[] _localAllElements = new String[allElements.length];

    for (int i = 0; i < allElements.length; i++)
        if (allElements[i] != null)
            _localAllElements[i] = allElements[i];

    return _localAllElements;
}

“null” 是否总是在开头或结尾? - obataku
首先我通过以下方式创建了一个数组 - String[] x = new String[10]; 然后我通过以下方式添加值 - x[a8] += " " + planetName1Tr[a9]; 在这种情况下,如果添加的值为空,则会出现“null Sun Moon”等情况。现在我想要删除这个 null。 - Kumar
你可能完全可以避免清洗任何东西。 - obataku
6个回答

2
抽象化@az的答案,这适用于任何类类型:
@SuppressWarnings("unchecked")
public static <T> T[] clean(T[] a) {
    List<T> list = new ArrayList<T>(Arrays.asList(a));
    list.removeAll(Collections.singleton(null));
    return list.toArray((T[]) Array.newInstance(a.getClass().getComponentType(), list.size()));
}

2
你正在创建一个与原始数组大小相同的数组。因此,它与原始数组相同,因为你复制非空值和默认值为空。
请执行以下操作:
public static String[] removeElements(String[] allElements) {
    // 1 : count
    int n = 0;
    for (int i = 0; i < allElements.length; i++)
        if (allElements[i] != null) n++;

    // 2 : allocate new array
    String[] _localAllElements = new String[n];

    // 3 : copy not null elements
    int j = 0;
    for (int i = 0; i < allElements.length; i++)
        if (allElements[i] != null)
            _localAllElements[j++] = allElements[i];

    return _localAllElements;
}

没有任何理由进行两次遍历。 - obataku
1
@veer,您需要计算非空字符串的数量以便分配大小合适的数组。或者您可以进行另一次更加费时的复制。 - Denys Séguret
你只需要检查一次 null 值! - obataku
实际上,Arrays.copyOf 可能与您手动复制的速度一样快,更不用说您必须两次将每个元素与 "null" 进行比较了 ;) - obataku
你正在改变初始数组,而我没有。这就是你似乎只进行了一次复制操作的原因。但这只是一个细节。 - Denys Séguret
你看了我的评论吗?如果你创建一个方法,提供一个新的数组并保持源数组不变(如问题中所述),那么你需要先复制数组,因此你会进行两次复制操作,而我只进行一次。但正如我之前所说,这只是一个细节,你的解决方案完全正确(而且更短),差异的重要性取决于使用情况,不值得花时间争论... - Denys Séguret

2
public static String[] clean(final String[] v) {
  int r, w;
  final int n = r = w = v.length;
  while (r > 0) {
    final String s = v[--r];
    if (!s.equals("null")) {
      v[--w] = s;
    }
  }
  return Arrays.copyOfRange(v, w, n);
}

或者

public static String[] clean(final String[] v) {
  int r, w, n = r = w = v.length;
  while (r > 0) {
    final String s = v[--r];
    if (!s.equals("null")) {
      v[--w] = s;
    }
  }
  final String[] c = new String[n -= w];
  System.arraycopy(v, w, c, 0, n);
  return c;
}

运行良好...

public static void main(final String[] argv) {
  final String[] source = new String[] { "Mars", "null", "Saturn", "null", "Mars" };
  assert Arrays.equals(clean(source), new String[] { "Mars", "Saturn", "Mars" });
}

1

如果您希望数组仅包含非空值(即结果数组将为["Mars", "Saturn", "Mars"]),那么我会将其视为两个部分的问题。

首先,您必须确定新数组的大小。从检查中,很容易看出它是3,但您需要计算它们以便以编程方式计算。您可以通过以下方式实现:

// Calculate the size for the new array.
int newSize = 0;
for (int i = 0; i < allElements.length; i++)    {
    if (allElements[i] != null) {
        newSize++;
    }
}

其次,您需要创建一个具有相应大小的新数组。然后,您可以将所有非空元素放入新数组中,就像您之前所做的那样。
// Populate the new array.
String[] _localAllElements = new String[newSize];
int newIndex = 0;
for (int i = 0; i < allElements.length; i++) {
    if (allElements[i] != null) {
        _localAllElements[newIndex] = allElements[i];
        newIndex++;
    }
}

// Return the new array.
return _localAllElements;

您可以将这两个组件合并为您的results方法的新内容。请查看完整的组合代码和实时示例输出此处


0

这是一个非常古老的问题,但这个Java 8+的解决方案可能对某些人有用:

public static String[] removeElements(String[] allElements) { return Arrays.stream(allElements) .filter(Objects::nonNull) .collect(Collectors.toArray()); } 或者如果你像我一样喜欢可读性强的代码,不想让静态方法妨碍你,你可以使用静态导入来进一步简化:

public static String[] removeElements(String[] allElements) { return stream(allElements).filter(Objects::nonNull).collect(toArray()); }


没有 Collectors.toArray()。要从 Stream 中获取一个 String[],你必须直接在 Stream 上调用 .toArray(String[]::new) - Holger

0
public static String[] removeElements(String[] allElements) {
    String[] _localAllElements = new String[allElements.length];
    int j = 0;
    for (int i = 0; i < allElements.length; i++)
        if ( allElements[i] != null && !allElements[i].equals(""))
            _localAllElements[j++] = allElements[i];

    return _localAllElements;
}

如果发现 null 或 "",它会在新的字符串数组末尾留下空字符串。但是它无法正常工作。 - Christos Papoulas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接