【问题标题】:Java: Comparing two string arrays and removing elements that exist in both arraysJava:比较两个字符串数组并删除两个数组中存在的元素
【发布时间】:2010-11-17 03:04:36
【问题描述】:

这主要是一个性能问题。我有一个字符串数组 AllUids 中存在的所有用户的主列表。我还有一个字符串数组 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);

ActiveUid 如下所示:

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

谢谢大家, 显然我可以想出循环等,但我不确定它是否有效。这是每天都会在生产机器上运行的东西。

【问题讨论】:

    标签: java arrays string


    【解决方案1】:

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

    Collection removeAll(Collection collection,
                         Collection remove)
    

    如果您使用用户列表而不是数组,那应该可以满足您的需求。您可以使用 Arrays.asList() 轻松地将数组转换为列表,所以...

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

    相当整洁...

    【讨论】:

    • CollectionUtils 对我不起作用,但如果我调用 ActiveUids.removeall(EndUids),它会完美运行。我最终改变了存储字符串的方式。我使用以下内容创建了一个哈希集: HashSet ActiveUids = new HashSet ();谢谢大家的帮助。这正是我想要的!
    • 可以在安卓上使用吗? :S
    【解决方案2】:

    您不能从数组中“删除”元素。您可以将它们设置为 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);
    

    这给人一种更实用的感觉。

    【讨论】:

    • 这种方法有点令人惊讶的是Sets.difference 返回一个view。如果您真的希望activeUids 成为“正常”Set(即:如果allUidsendUids 发生变化,则其值不会改变,并且调用size() 是O(1) ),您可能应该立即将 Sets.difference 的结果传递给构造 Set 的东西。例如:Sets.newHashSet(Sets.difference(a, b))
    【解决方案3】:
    /*
     * 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);
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

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

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

      尽管您确实应该尽量避免使用数组并偏爱集合。

      【讨论】:

        【解决方案5】:

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

        顺便说一句,PHP“数组”实际上是哈希映射。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            【解决方案7】:
                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);
            

            【讨论】:

            • 不鼓励仅使用代码回答。最好解释一下这段代码 sn -p 解决问题的原因和方式
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-04-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-19
            • 1970-01-01
            相关资源
            最近更新 更多