Java:比较两个字符串数组并删除两个数组中存在的元素

时间:2009-08-05 18:46:44

标签: java arrays string

这主要是性能问题。我有一个String数组AllUids中存在的所有用户的主列表。我还有一个String数组EndUids中存在的所有最终用户的列表。

我在Java工作,我的目标是从主列表AllUids中删除末端日期数组中存在的所有用户。我知道PHP有一个名为array_diff的函数。

我很好奇Java是否有任何可以比较两个数组并删除两者相似的元素。我的目标是这里的表现,这就是我询问内置功能的原因。我不想添加任何特殊包。

我考虑过编写一个递归函数,但它似乎效率低下。两个列表中都有数千个用户。为了存在于结束日期列表中,您必须存在于AllUids列表中,直到被删除。

示例:

String[] AllUids = {"Joe", "Tom", "Dan", "Bill", "Hector", "Ron"};

String[] EndUids = {"Dan", "Hector", "Ron"};

我正在寻找的功能:

String[] ActiveUids = AllUids.RemoveSimilar(EndUids);

ActiveUids看起来像这样:

{"Joe", "Tom", "Bill"}

谢谢大家, 显然我可以提出循环等但我不相信它会有效。这将是每天在生产机器上运行的东西。

7 个答案:

答案 0 :(得分:13)

Commons Collections有一个名为CollectionUtils的类和一个名为removeAll的静态方法,它接受一个初始列表和要从该列表中删除的东西列表:

Collection removeAll(Collection collection,
                     Collection remove)

如果您使用用户列表而不是数组,那么应该按照您的意愿执行操作。您可以使用Arrays.asList()so ...

轻松地将数组转换为列表
Collection ActiveUids = CollectionUtils.removeAll(Arrays.asList(AllUids), 
                                                  Arrays.asList(EndUids))

编辑:我还对Commons Collections进行了一些挖掘,并在Commons Collections中找到了以下ListUtils解决方案:

List diff = ListUtils.subtract(Arrays.asList(AllUids), Arrays.asList(EndUids));

非常整洁......

答案 1 :(得分:6)

您无法从数组中“删除”元素。您可以将它们设置为null,但数组的大小是固定的。

可以使用java.util.SetremoveAll从另一个人那里拿走一套,但我更愿意使用Google Collections Library

Set<String> allUids = Sets.newHashSet("Joe", "Tom", "Dan",
                                      "Bill", "Hector", "Ron");
Set<String> endUids = Sets.newHashSet("Dan", "Hector", "Ron");
Set<String> activeUids = Sets.difference(allUids, endUids);

它具有更多功能感。

答案 2 :(得分:4)

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Bireswhar
 */
import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Repeated {

    public static void main(String[] args) {
//        Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
//        Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));
//
//        listOne.retainAll( listTwo );
//        System.out.println( listOne );

        String[] s1 = {"ram", "raju", "seetha"};
        String[] s2 = {"ram"};
        List<String> s1List = new ArrayList(Arrays.asList(s1));
        for (String s : s2) {
            if (s1List.contains(s)) {
                s1List.remove(s);
            } else {
                s1List.add(s);
            }
             System.out.println("intersect on " + s1List);
        }
    }
}

答案 3 :(得分:3)

最简单的解决方案可能是将所有元素放入Set中,然后使用removeAll。您可以从这样的数组转换为Set:

Set<String> activeUids = new HashSet<String>(Arrays.asList(activeUidsArray));

尽管你应该尽量避免使用数组并支持集合。

答案 4 :(得分:3)

不要为此使用数组,请使用Collection和removeAll()方法。至于性能:除非你做一些导致O(n ^ 2)运行时的愚蠢行为,否则就算了。这是不成熟的优化,无用/有害的。 “成千上万的用户”并不算什么,除非你每秒都做数千次。

BTW,PHP“数组”实际上是哈希映射。

答案 5 :(得分:1)

您可以将这些字符串放入Collection,然后使用removeAll方法。

答案 6 :(得分:0)

    String s1 = "a,b,c,d";
    String s2 = "x,y,z,a,b,c";
    Set<String> set1 = new HashSet<String>();
    Set<String> set2 = new HashSet<String>();

    Set<String> set11 = new HashSet<String>();

    String[] splitS1 = s1.split(",");
    String[] splitS2 = s2.split(",");

    for(String s3:splitS1){
        set1.add(s3);
        set11.add(s3);
    }

    for(String s4:splitS2){
        set2.add(s4);
    }
    set1.removeAll(set2);
    set2.removeAll(set11);
    set1.addAll(set2);
    System.out.println(set1);