简体   繁体   English

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

[英]Java: Comparing two string arrays and removing elements that exist in both arrays

This is mainly a performance questions. 这主要是一个表现问题。 I have a master list of all users existing in a String array AllUids. 我有一个String数组AllUids中存在的所有用户的主列表。 I also have a list of all end dated users existing in a String array EndUids. 我还有一个String数组EndUids中存在的所有最终用户的列表。

I am working in Java and my goal is to remove any users that exist in the end dated array from the master list AllUids. 我在Java工作,我的目标是从主列表AllUids中删除最终日期数组中存在的任何用户。 I know PHP has a function called array_diff. 我知道PHP有一个名为array_diff的函数。

I was curious if Java has anything that will compare two arrays and remove elements that are similar in both. 我很好奇Java是否有任何可以比较两个数组并删除两者相似的元素。 My objective is performance here which is why I asked about a built in function. 我的目标是这里的表现,这就是我询问内置功能的原因。 I do not want to add any special packages. 我不想添加任何特殊包。

I thought about writing a recursive function but it just seems like it will be inefficient. 我想过写一个递归函数,但看起来效率很低。 There are thousands of users in both lists. 两个列表中都有数千个用户。 In order to exist in the end dated list, you must exist in the AllUids list, that is until removed. 要存在于结束日期列表中,您必须存在于AllUids列表中,直到被删除。

Example: 例:

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

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

Functionality I am looking for: 我正在寻找的功能:

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

ActiveUids would look like this: ActiveUids看起来像这样:

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

Thank you all, Obviously I can come up with loops and such but I am not confident that it will be efficient. 谢谢大家,显然我可以提出循环等但我不相信它会有效率。 This is something that will run on production machines everyday. 这是每天在生产机器上运行的东西。

Commons Collections has a class called CollectionUtils and a static method called removeAll which takes an initial list and a list of thing to remove from that list: Commons Collections有一个名为CollectionUtils的类和一个名为removeAll的静态方法,它接受一个初始列表和一个要从该列表中删除的东西列表:

Collection removeAll(Collection collection,
                     Collection remove)

That should do what you want provided you use lists of users rather than arrays. 如果你使用用户列表而不是数组,那应该做你想要的。 You can convert your array into a list very easily with Arrays.asList() so... 您可以使用Arrays.asList()将数组转换为一个列表,以便...

Collection ActiveUids = CollectionUtils.removeAll(Arrays.asList(AllUids), 
                                                  Arrays.asList(EndUids))

EDIT: I also did a bit of digging with this into Commons Collections and found the following solution with ListUtils in Commons Collections as well: 编辑:我也对Commons Collections进行了一些挖掘,并在Commons Collections中找到了ListUtils的以下解决方案:

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

Pretty neat... 很简约...

You can't "remove" elements from arrays. 您无法从数组中“删除”元素。 You can set them to null, but arrays are of fixed size. 您可以将它们设置为null,但数组的大小是固定的。

You could use java.util.Set and removeAll to take one set away from another, but I'd prefer to use the Google Collections Library : 可以使用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);

That has a more functional feel to it. 这有一个更实用的感觉。

/*
 * 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);
        }
    }
}

The easiest solution is probably to put all of the elements into a Set and then use removeAll. 最简单的解决方案可能是将所有元素放入Set中,然后使用removeAll。 You can convert to a Set from an array like this: 您可以从这样的数组转换为Set:

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

though you should really try to avoid using arrays and favor collections. 虽然你应该尽量避免使用数组和青睐集合。

Don't use arrays for this, use Collection and the removeAll() method. 不要为此使用数组,使用Collection和removeAll()方法。 As for performance: unless you do something idiotic that leads to O(n^2) runtime, just forget about it. 至于性能:除非你做一些导致O(n ^ 2)运行时的愚蠢行为,否则就算了。 It's premature optimization, the useless/harmful kind. 这是不成熟的优化,无用/有害的。 "thousands of users" is nothing, unless you're doing it thousands of times each second. “成千上万的用户”并不算什么,除非你每秒都做数千次。

BTW, PHP "arrays" are in fact hash maps. 顺便说一句,PHP“数组”实际上是哈希映射。

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

    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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM