如何从 Java 数组中删除对象?

发布于 2024-07-06 21:31:17 字数 215 浏览 7 评论 0原文

给定一个 n 对象数组,假设它是一个字符串数组,并且它具有以下值:

foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";

我需要做什么才能删除/删除所有字符串/数组中的对象等于“a”

Given an array of n Objects, let's say it is an array of strings, and it has the following values:

foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";

What do I have to do to delete/remove all the strings/objects equal to "a" in the array?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

瞄了个咪的 2024-07-13 21:31:18

如果您需要从数组中删除多个元素,而不将其转换为 List 或创建其他数组,则可以在 O(n) 内完成,而不依赖于要删除的项目数。

这里,a 是初始数组,int...r 是要删除的元素的不同有序索引(位置):

public int removeItems(Object[] a, int... r) {
    int shift = 0;                             
    for (int i = 0; i < a.length; i++) {       
        if (shift < r.length && i == r[shift])  // i-th item needs to be removed
            shift++;                            // increment `shift`
        else 
            a[i - shift] = a[i];                // move i-th item `shift` positions left
    }
    for (int i = a.length - shift; i < a.length; i++)
        a[i] = null;                            // replace remaining items by nulls

    return a.length - shift;                    // return new "length"
}  

小测试:

String[] a = {"0", "1", "2", "3", "4"};
removeItems(a, 0, 3, 4);                     // remove 0-th, 3-rd and 4-th items
System.out.println(Arrays.asList(a));        // [1, 2, null, null, null]

在您的任务中,您可以首先扫描数组收集“a”的位置,然后调用removeItems()

If you need to remove multiple elements from array without converting it to List nor creating additional array, you may do it in O(n) not dependent on count of items to remove.

Here, a is initial array, int... r are distinct ordered indices (positions) of elements to remove:

public int removeItems(Object[] a, int... r) {
    int shift = 0;                             
    for (int i = 0; i < a.length; i++) {       
        if (shift < r.length && i == r[shift])  // i-th item needs to be removed
            shift++;                            // increment `shift`
        else 
            a[i - shift] = a[i];                // move i-th item `shift` positions left
    }
    for (int i = a.length - shift; i < a.length; i++)
        a[i] = null;                            // replace remaining items by nulls

    return a.length - shift;                    // return new "length"
}  

Small testing:

String[] a = {"0", "1", "2", "3", "4"};
removeItems(a, 0, 3, 4);                     // remove 0-th, 3-rd and 4-th items
System.out.println(Arrays.asList(a));        // [1, 2, null, null, null]

In your task, you can first scan array to collect positions of "a", then call removeItems().

停滞 2024-07-13 21:31:18

这里有很多答案 - 我看到的问题是你没有说为什么你使用数组而不是集合,所以让我提出几个原因以及适用的解决方案(大多数解决方案这里已经在其他问题中得到了回答,所以我不再赘述):

原因:您不知道集合包存在或不信任它

解决方案:使用集合。

如果您打算从中间添加/删除,请使用 LinkedList。 如果您确实担心大小或经常在集合中间建立索引,请使用 ArrayList。 这两个都应该有删除操作。

原因:您担心大小或想要控制内存分配

解决方案:使用具有特定初始大小的 ArrayList。

ArrayList 只是一个可以自行扩展的数组,但并不总是需要这样做。 添加/删除项目会非常聪明,但是如果您要从中间插入/删除很多项目,请使用 LinkedList。

原因:您有一个数组传入和一个数组传出 - 所以您想对数组进行操作

解决方案:将其转换为 ArrayList,删除该项目并将其转换回来

原因:您认为如果您自己动手就可以编写更好的代码

解决方案:您不能,请使用数组或链接列表。

原因:这是一个类分配,您不被允许或者由于某种原因您无权访问集合 api

假设:您需要新数组成为正确的“大小”

解决方案:
扫描数组中的匹配项并对其进行计数。 创建一个正确大小的新数组(原始大小 - 匹配数)。 重复使用 System.arraycopy 将您希望保留的每组项目复制到新数组中。 如果这是一个类分配,并且您无法使用 System.arraycopy,只需在循环中手动复制它们,但不要在生产代码中执行此操作,因为它要慢得多。 (这些解决方案在其他答案中都有详细介绍)

原因:您需要运行裸机

假设:您不得分配不必要的空间或花费太长时间

假设:您正在跟踪数组中使用的大小(长度)分开,因为否则你必须重新分配数组以进行删除/插入。

您可能想要这样做的一个例子:单个基元数组(比方说 int 值)占用了您的 ram 的很大一部分——比如 50%! ArrayList 会强制将它们放入指向 Integer 对象的指针列表中,这将使用几倍的内存量。

解决方案:迭代数组,每当找到要删除的元素(我们称之为元素 n)时,使用 System.arraycopy 将数组的尾部复制到“已删除”元素上(源和目标是相同的数组) - 它足够聪明,可以按照正确的方向进行复制,因此内存不会覆盖自身:

 System.arraycopy(ary, n+1, ary, n, length-n) 
 length--;

如果您一次删除多个元素,您可能会希望比这更聪明。 您只需移动一个“匹配”与下一个“匹配”之间的区域,而不是整个尾部,并且一如既往地避免将任何块移动两次。

在最后一种情况下,您绝对必须自己完成这项工作,并且使用 System.arraycopy 实际上是唯一的方法,因为它将为您的计算机体系结构选择移动内存的最佳方法 - 它应该快很多倍比您自己可以合理编写的任何代码都要好。

There are a lot of answers here--the problem as I see it is that you didn't say WHY you are using an array instead of a collection, so let me suggest a couple reasons and which solutions would apply (Most of the solutions have already been answered in other questions here, so I won't go into too much detail):

reason: You didn't know the collection package existed or didn't trust it

solution: Use a collection.

If you plan on adding/deleting from the middle, use a LinkedList. If you are really worried about size or often index right into the middle of the collection use an ArrayList. Both of these should have delete operations.

reason: You are concerned about size or want control over memory allocation

solution: Use an ArrayList with a specific initial size.

An ArrayList is simply an array that can expand itself, but it doesn't always need to do so. It will be very smart about adding/removing items, but again if you are inserting/removing a LOT from the middle, use a LinkedList.

reason: You have an array coming in and an array going out--so you want to operate on an array

solution: Convert it to an ArrayList, delete the item and convert it back

reason: You think you can write better code if you do it yourself

solution: you can't, use an Array or Linked list.

reason: this is a class assignment and you are not allowed or you do not have access to the collection apis for some reason

assumption: You need the new array to be the correct "size"

solution:
Scan the array for matching items and count them. Create a new array of the correct size (original size - number of matches). use System.arraycopy repeatedly to copy each group of items you wish to retain into your new Array. If this is a class assignment and you can't use System.arraycopy, just copy them one at a time by hand in a loop but don't ever do this in production code because it's much slower. (These solutions are both detailed in other answers)

reason: you need to run bare metal

assumption: you MUST not allocate space unnecessarily or take too long

assumption: You are tracking the size used in the array (length) separately because otherwise you'd have to reallocate your array for deletes/inserts.

An example of why you might want to do this: a single array of primitives (Let's say int values) is taking a significant chunk of your ram--like 50%! An ArrayList would force these into a list of pointers to Integer objects which would use a few times that amount of memory.

solution: Iterate over your array and whenever you find an element to remove (let's call it element n), use System.arraycopy to copy the tail of the array over the "deleted" element (Source and Destination are same array)--it is smart enough to do the copy in the correct direction so the memory doesn't overwrite itself:

 System.arraycopy(ary, n+1, ary, n, length-n) 
 length--;

You'll probably want to be smarter than this if you are deleting more than one element at a time. You would only move the area between one "match" and the next rather than the entire tail and as always, avoid moving any chunk twice.

In this last case, you absolutely must do the work yourself, and using System.arraycopy is really the only way to do it since it's going to choose the best possibly way to move memory for your computer architecture--it should be many times faster than any code you could reasonably write yourself.

蓝咒 2024-07-13 21:31:18

关于创建一个列表然后删除然后返回数组的一些事情让我觉得错误。 还没有测试过,但我认为下面的效果会更好。 是的,我可能过度地进行了预优化。

boolean [] deleteItem = new boolean[arr.length];
int size=0;
for(int i=0;i<arr.length;i==){
   if(arr[i].equals("a")){
      deleteItem[i]=true;
   }
   else{
      deleteItem[i]=false;
      size++;
   }
}
String[] newArr=new String[size];
int index=0;
for(int i=0;i<arr.length;i++){
   if(!deleteItem[i]){
      newArr[index++]=arr[i];
   }
}

Something about the make a list of it then remove then back to an array strikes me as wrong. Haven't tested, but I think the following will perform better. Yes I'm probably unduly pre-optimizing.

boolean [] deleteItem = new boolean[arr.length];
int size=0;
for(int i=0;i<arr.length;i==){
   if(arr[i].equals("a")){
      deleteItem[i]=true;
   }
   else{
      deleteItem[i]=false;
      size++;
   }
}
String[] newArr=new String[size];
int index=0;
for(int i=0;i<arr.length;i++){
   if(!deleteItem[i]){
      newArr[index++]=arr[i];
   }
}
画离情绘悲伤 2024-07-13 21:31:18

我意识到这是一篇非常老的帖子,但这里的一些答案帮助了我,所以这是我的二便士半便士的价值!

在发现我正在写回的数组需要调整大小之前,我花了很长一段时间才使其正常工作,除非对 ArrayList 所做的更改使列表大小保持不变。

如果您正在修改的 ArrayList 最终的元素数量比开始时多或少,则 List.toArray() 行将导致异常,因此您需要一些东西例如 List.toArray(new String[] {})List.toArray(new String[0]) 以便创建具有新(正确)大小的数组。

现在我知道了,这听起来很明显。 对于一个正在学习新的、不熟悉的代码结构的 Android/Java 新手来说,这并不是那么明显,而且从这里之前的一些帖子来看,这一点也不是很明显,所以我只是想让其他像我一样摸不着头脑的人明白这一点。 !

I realise this is a very old post, but some of the answers here helped me out, so here's my tuppence' ha'penny's worth!

I struggled getting this to work for quite a while before before twigging that the array that I'm writing back into needed to be resized, unless the changes made to the ArrayList leave the list size unchanged.

If the ArrayList that you're modifying ends up with greater or fewer elements than it started with, the line List.toArray() will cause an exception, so you need something like List.toArray(new String[] {}) or List.toArray(new String[0]) in order to create an array with the new (correct) size.

Sounds obvious now that I know it. Not so obvious to an Android/Java newbie who's getting to grips with new and unfamiliar code constructs and not obvious from some of the earlier posts here, so just wanted to make this point really clear for anybody else scratching their heads for hours like I was!

当爱已成负担 2024-07-13 21:31:18

初始数组

   int[] array = {5,6,51,4,3,2};

如果要删除索引 2 的 51,请使用以下

 for(int i = 2; i < array.length -1; i++){
    array[i] = array[i + 1];
  }

Initial array

   int[] array = {5,6,51,4,3,2};

if you want remove 51 that is index 2, use following

 for(int i = 2; i < array.length -1; i++){
    array[i] = array[i + 1];
  }
喵星人汪星人 2024-07-13 21:31:18

编辑:

数组中具有空值的点已被清除。 抱歉我的评论。

原文:

嗯...该行将

array = list.toArray(array);

数组中已删除元素所在的所有间隙替换为 null。 这可能是危险,因为元素被删除,但数组的长度保持不变!

如果您想避免这种情况,请使用新数组作为 toArray() 的参数。 如果您不想使用removeAll,则可以选择Set:

        String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

        System.out.println(Arrays.toString(array));

        Set<String> asSet = new HashSet<String>(Arrays.asList(array));
        asSet.remove("a");
        array = asSet.toArray(new String[] {});

        System.out.println(Arrays.toString(array));

给出:

[a, bc, dc, a, ef]
[dc, ef, bc]

Chris Yester Young 输出当前接受的答案:

[a, bc, dc, a, ef]
[bc, dc, ef, null, ef]

代码中

    String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

    System.out.println(Arrays.toString(array));

    List<String> list = new ArrayList<String>(Arrays.asList(array));
    list.removeAll(Arrays.asList("a"));
    array = list.toArray(array);        

    System.out.println(Arrays.toString(array));

不留下任何空值。

EDIT:

The point with the nulls in the array has been cleared. Sorry for my comments.

Original:

Ehm... the line

array = list.toArray(array);

replaces all gaps in the array where the removed element has been with null. This might be dangerous, because the elements are removed, but the length of the array remains the same!

If you want to avoid this, use a new Array as parameter for toArray(). If you don`t want to use removeAll, a Set would be an alternative:

        String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

        System.out.println(Arrays.toString(array));

        Set<String> asSet = new HashSet<String>(Arrays.asList(array));
        asSet.remove("a");
        array = asSet.toArray(new String[] {});

        System.out.println(Arrays.toString(array));

Gives:

[a, bc, dc, a, ef]
[dc, ef, bc]

Where as the current accepted answer from Chris Yester Young outputs:

[a, bc, dc, a, ef]
[bc, dc, ef, null, ef]

with the code

    String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

    System.out.println(Arrays.toString(array));

    List<String> list = new ArrayList<String>(Arrays.asList(array));
    list.removeAll(Arrays.asList("a"));
    array = list.toArray(array);        

    System.out.println(Arrays.toString(array));

without any null values left behind.

妄司 2024-07-13 21:31:18

我对这个问题的一点贡献。

public class DeleteElementFromArray {
public static String foo[] = {"a","cc","a","dd"};
public static String search = "a";


public static void main(String[] args) {
    long stop = 0;
    long time = 0;
    long start = 0;
    System.out.println("Searched value in Array is: "+search);
    System.out.println("foo length before is: "+foo.length);
    for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
    System.out.println("==============================================================");
    start = System.nanoTime();
    foo = removeElementfromArray(search, foo);
    stop = System.nanoTime();
    time = stop - start;
    System.out.println("Equal search took in nano seconds = "+time);
    System.out.println("==========================================================");
    for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
}
public static String[] removeElementfromArray( String toSearchfor, String arr[] ){
     int i = 0;
     int t = 0;
     String tmp1[] = new String[arr.length];     
         for(;i<arr.length;i++){
              if(arr[i] == toSearchfor){     
              i++;
              }
             tmp1[t] = arr[i];
             t++;
     }   
     String tmp2[] = new String[arr.length-t];   
     System.arraycopy(tmp1, 0, tmp2, 0, tmp2.length);
     arr = tmp2; tmp1 = null; tmp2 = null;
    return arr;
}

}

My little contribution to this problem.

public class DeleteElementFromArray {
public static String foo[] = {"a","cc","a","dd"};
public static String search = "a";


public static void main(String[] args) {
    long stop = 0;
    long time = 0;
    long start = 0;
    System.out.println("Searched value in Array is: "+search);
    System.out.println("foo length before is: "+foo.length);
    for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
    System.out.println("==============================================================");
    start = System.nanoTime();
    foo = removeElementfromArray(search, foo);
    stop = System.nanoTime();
    time = stop - start;
    System.out.println("Equal search took in nano seconds = "+time);
    System.out.println("==========================================================");
    for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
}
public static String[] removeElementfromArray( String toSearchfor, String arr[] ){
     int i = 0;
     int t = 0;
     String tmp1[] = new String[arr.length];     
         for(;i<arr.length;i++){
              if(arr[i] == toSearchfor){     
              i++;
              }
             tmp1[t] = arr[i];
             t++;
     }   
     String tmp2[] = new String[arr.length-t];   
     System.arraycopy(tmp1, 0, tmp2, 0, tmp2.length);
     arr = tmp2; tmp1 = null; tmp2 = null;
    return arr;
}

}

吹梦到西洲 2024-07-13 21:31:18

这取决于你所说的“删除”是什么意思? 数组是固定大小的构造 - 您无法更改其中元素的数量。 因此,您可以 a) 创建一个新的、更短的数组,其中不包含您不需要的元素,或者 b) 将您不需要的条目分配给指示其“空”状态的内容; 如果您不使用基元,通常为 null。

在第一种情况下,从数组创建一个列表,删除元素,然后从列表创建一个新数组。 如果性能很重要,请迭代数组,将不应删除的任何元素分配到列表中,然后从列表中创建一个新数组。 在第二种情况下,只需遍历数组条目并将 null 分配给数组条目即可。

It depends on what you mean by "remove"? An array is a fixed size construct - you can't change the number of elements in it. So you can either a) create a new, shorter, array without the elements you don't want or b) assign the entries you don't want to something that indicates their 'empty' status; usually null if you are not working with primitives.

In the first case create a List from the array, remove the elements, and create a new array from the list. If performance is important iterate over the array assigning any elements that shouldn't be removed to a list, and then create a new array from the list. In the second case simply go through and assign null to the array entries.

愿得七秒忆 2024-07-13 21:31:18

呃,我无法正确显示代码。 抱歉,我已经成功了。 再次抱歉,我认为我没有正确阅读问题。

String  foo[] = {"a","cc","a","dd"},
remove = "a";
boolean gaps[] = new boolean[foo.length];
int newlength = 0;

for (int c = 0; c<foo.length; c++)
{
    if (foo[c].equals(remove))
    {
        gaps[c] = true;
        newlength++;
    }
    else 
        gaps[c] = false;

    System.out.println(foo[c]);
}

String newString[] = new String[newlength];

System.out.println("");

for (int c1=0, c2=0; c1<foo.length; c1++)
{
    if (!gaps[c1])
    {
        newString[c2] = foo[c1];
        System.out.println(newString[c2]);
        c2++;
    }
}

Arrgh, I can't get the code to show up correctly. Sorry, I got it working. Sorry again, I don't think I read the question properly.

String  foo[] = {"a","cc","a","dd"},
remove = "a";
boolean gaps[] = new boolean[foo.length];
int newlength = 0;

for (int c = 0; c<foo.length; c++)
{
    if (foo[c].equals(remove))
    {
        gaps[c] = true;
        newlength++;
    }
    else 
        gaps[c] = false;

    System.out.println(foo[c]);
}

String newString[] = new String[newlength];

System.out.println("");

for (int c1=0, c2=0; c1<foo.length; c1++)
{
    if (!gaps[c1])
    {
        newString[c2] = foo[c1];
        System.out.println(newString[c2]);
        c2++;
    }
}
停滞 2024-07-13 21:31:18

将复制除索引 i 之外的所有元素:

if(i == 0){
                System.arraycopy(edges, 1, copyEdge, 0, edges.length -1 );
            }else{
                System.arraycopy(edges, 0, copyEdge, 0, i );
                System.arraycopy(edges, i+1, copyEdge, i, edges.length - (i+1) );
            }

Will copy all elements except the one with index i:

if(i == 0){
                System.arraycopy(edges, 1, copyEdge, 0, edges.length -1 );
            }else{
                System.arraycopy(edges, 0, copyEdge, 0, i );
                System.arraycopy(edges, i+1, copyEdge, i, edges.length - (i+1) );
            }
银河中√捞星星 2024-07-13 21:31:18

如果元素的顺序无关紧要。 您可以在元素 foo[x] 和 foo[0] 之间交换,然后调用 foo.drop(1)。

foo.drop(n) 从数组中删除 (n) 个第一个元素。

我想这是最简单且资源有效的方法。

PSindexOf可以通过多种方式实现,这是我的版本。

Integer indexOf(String[] arr, String value){
    for(Integer i = 0 ; i < arr.length; i++ )
        if(arr[i] == value)
            return i;         // return the index of the element
    return -1                 // otherwise -1
}

while (true) {
   Integer i;
   i = indexOf(foo,"a")
   if (i == -1) break;
   foo[i] = foo[0];           // preserve foo[0]
   foo.drop(1);
}

If it doesn't matter the order of the elements. you can swap between the elements foo[x] and foo[0], then call foo.drop(1).

foo.drop(n) removes (n) first elements from the array.

I guess this is the simplest and resource efficient way to do.

PS: indexOf can be implemented in many ways, this is my version.

Integer indexOf(String[] arr, String value){
    for(Integer i = 0 ; i < arr.length; i++ )
        if(arr[i] == value)
            return i;         // return the index of the element
    return -1                 // otherwise -1
}

while (true) {
   Integer i;
   i = indexOf(foo,"a")
   if (i == -1) break;
   foo[i] = foo[0];           // preserve foo[0]
   foo.drop(1);
}
朱染 2024-07-13 21:31:18

删除 仅几个相同条目中​​的第一个
使用 lambda

boolean[] done = {false};
String[] arr = Arrays.stream( foo ).filter( e ->
  ! (! done[0] && Objects.equals( e, item ) && (done[0] = true) ))
    .toArray(String[]::new);

可以删除 null 条目

to remove  only the first  of several equal entries
with a lambda

boolean[] done = {false};
String[] arr = Arrays.stream( foo ).filter( e ->
  ! (! done[0] && Objects.equals( e, item ) && (done[0] = true) ))
    .toArray(String[]::new);

can remove null entries

对你而言 2024-07-13 21:31:18

字符串数组中,

在像String name = 'abcdeafbd e' // 可能像 String name = 'aa bb cde aa f bb d e' 这样的

我构建了以下类,

class clearname{
def parts
def tv
public def str = ''
String name
clearname(String name){
    this.name = name
    this.parts = this.name.split(" ")
    this.tv = this.parts.size()
}
public String cleared(){

        int i
        int k
        int j=0        
    for(i=0;i<tv;i++){
        for(k=0;k<tv;k++){
            if(this.parts[k] == this.parts[i] && k!=i){
               this.parts[k] = '';
                j++
            }
        }
    }
    def str = ''
    for(i=0;i<tv;i++){
        if(this.parts[i]!='')

           this.str += this.parts[i].trim()+' '
    } 
    return this.str    
}}



return new clearname(name).cleared()

得到了这个结果

bcdef

希望这段代码可以帮助任何人
问候

In an array of Strings like

String name = 'a b c d e a f b d e' // could be like String name = 'aa bb c d e aa f bb d e'

I build the following class

class clearname{
def parts
def tv
public def str = ''
String name
clearname(String name){
    this.name = name
    this.parts = this.name.split(" ")
    this.tv = this.parts.size()
}
public String cleared(){

        int i
        int k
        int j=0        
    for(i=0;i<tv;i++){
        for(k=0;k<tv;k++){
            if(this.parts[k] == this.parts[i] && k!=i){
               this.parts[k] = '';
                j++
            }
        }
    }
    def str = ''
    for(i=0;i<tv;i++){
        if(this.parts[i]!='')

           this.str += this.parts[i].trim()+' '
    } 
    return this.str    
}}



return new clearname(name).cleared()

getting this result

a b c d e f

hope this code help anyone
Regards

潇烟暮雨 2024-07-13 21:31:18

将 null 分配给数组位置。

Assign null to the array locations.

风月客 2024-07-13 21:31:17

[如果您想要一些现成的代码,请滚动到我的“Edit3”(剪切后)。 其余的内容供后代使用。]

为了充实Dustman 的想法

List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);

编辑:我现在使用数组。 asList 而不是 Collections.singleton:单例仅限于一个条目,而 asList 方法允许您添加其他字符串以便稍后过滤:Arrays.asList(“a”,“b”,“c”)

Edit2:上述方法保留了相同的数组(因此数组仍然是相同的长度); 最后一个元素之后的元素设置为 null。 如果您想要一个大小完全符合要求的数组,请使用以下代码:

array = list.toArray(new String[0]);

Edit3:如果您在同一个类中经常使用此代码,您可能希望考虑将其添加到您的类中:

private static final String[] EMPTY_STRING_ARRAY = new String[0];

然后该函数将变为:

List<String> list = new ArrayList<>();
Collections.addAll(list, array);
list.removeAll(Arrays.asList("a"));
array = list.toArray(EMPTY_STRING_ARRAY);

这将停止在堆中散布无用的空字符串数组,否则每次调用函数时这些数组都会被newed。

愤世嫉俗者的建议(见评论)也将有助于堆乱扔,为了公平起见,我应该提到它:

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

我更喜欢我的方法,因为它可能更容易得到错误的显式大小(例如,调用 size() 放在错误的列表中)。

[If you want some ready-to-use code, please scroll to my "Edit3" (after the cut). The rest is here for posterity.]

To flesh out Dustman's idea:

List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);

Edit: I'm now using Arrays.asList instead of Collections.singleton: singleton is limited to one entry, whereas the asList approach allows you to add other strings to filter out later: Arrays.asList("a", "b", "c").

Edit2: The above approach retains the same array (so the array is still the same length); the element after the last is set to null. If you want a new array sized exactly as required, use this instead:

array = list.toArray(new String[0]);

Edit3: If you use this code on a frequent basis in the same class, you may wish to consider adding this to your class:

private static final String[] EMPTY_STRING_ARRAY = new String[0];

Then the function becomes:

List<String> list = new ArrayList<>();
Collections.addAll(list, array);
list.removeAll(Arrays.asList("a"));
array = list.toArray(EMPTY_STRING_ARRAY);

This will then stop littering your heap with useless empty string arrays that would otherwise be newed each time your function is called.

cynicalman's suggestion (see comments) will also help with the heap littering, and for fairness I should mention it:

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

I prefer my approach, because it may be easier to get the explicit size wrong (e.g., calling size() on the wrong list).

心如狂蝶 2024-07-13 21:31:17

Java 8 中的替代方案:

String[] filteredArray = Arrays.stream(array)
    .filter(e -> !e.equals(foo)).toArray(String[]::new);

An alternative in Java 8:

String[] filteredArray = Arrays.stream(array)
    .filter(e -> !e.equals(foo)).toArray(String[]::new);
暖风昔人 2024-07-13 21:31:17

使用Arrays.asList()从数组中创建一个List,并对所有适当的元素调用remove()。 然后在“List”上调用toArray()以再次将其恢复为数组。

性能不是很好,但是如果你正确封装它,你以后总是可以更快地做一些事情。

Make a List out of the array with Arrays.asList(), and call remove() on all the appropriate elements. Then call toArray() on the 'List' to make back into an array again.

Not terribly performant, but if you encapsulate it properly, you can always do something quicker later on.

雨巷深深 2024-07-13 21:31:17

你总是可以这样做:

int i, j;
for (i = j = 0; j < foo.length; ++j)
  if (!"a".equals(foo[j])) foo[i++] = foo[j];
foo = Arrays.copyOf(foo, i);

You can always do:

int i, j;
for (i = j = 0; j < foo.length; ++j)
  if (!"a".equals(foo[j])) foo[i++] = foo[j];
foo = Arrays.copyOf(foo, i);
琉璃繁缕 2024-07-13 21:31:17

您可以使用外部库:

org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)

它位于项目 Apache Commons Lang http://commons.apache.org/lang/

You can use external library:

org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)

It is in project Apache Commons Lang http://commons.apache.org/lang/

空‖城人不在 2024-07-13 21:31:17

请参阅下面的代码

ArrayList<String> a = new ArrayList<>(Arrays.asList(strings));
a.remove(i);
strings = new String[a.size()];
a.toArray(strings);

See code below

ArrayList<String> a = new ArrayList<>(Arrays.asList(strings));
a.remove(i);
strings = new String[a.size()];
a.toArray(strings);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文