【问题标题】:Changing a long[] into a Set. Error message: The method addAll in the type Collections is not applicable for the arguments (Set<Long>, long[])将 long[] 更改为 Set。错误消息:集合类型中的方法 addAll 不适用于参数 (Set<Long>, long[])
【发布时间】:2018-04-15 11:06:46
【问题描述】:

在一项家庭作业中,有人要求我在现有程序中创建一个名为 noDups() 的方法,该方法可以在不破坏顺序的情况下从先前排序的数组中删除重复项。该问题还指出它必须是具有 O(N) 的算法,并确保没有项目被移动超过一次,无论有多少重复项。

我最初尝试使用嵌套的 for 循环来循环并删除重复项,但发现这是 O(N^2)。我了解到您可以使用 Set 解决此问题。我尝试编写方法来获取 long[](程序使用的数组类型)数组并将其转换为集合,因为集合仅包含唯一值:

public long[] noDups(long[] target) { //Method for removing duplicates

        Set<Long> set = new HashSet<Long>();
        Collections.addAll(set, target);

        return target;
}

我不断收到标题中所述的错误:

"类型中的方法addAll(Collection, T...) 集合不适用于参数 (Set, long[])"

在我的方法看起来像这样但我有一个不同的错误之前:

public void noDups(long[] target){

    Set<long> set = new Hashset<long>(Arrays.asList(target));

我初始化 Set 错误吗?谁能告诉我如何摆脱错误或引导我朝着正确的方向将 long [] 转换为 Set。谢谢!

【问题讨论】:

    标签: java arrays collections set hashset


    【解决方案1】:

    如果你想删除重复的表单数组,你不需要使用HashMap,你可以使用Java 8 流API。即

     long[] dups = new long[]{1,2,3,4,4,4};
     long[] noDups = Arrays.stream(dups).distinct().toArray();
    

    【讨论】:

      【解决方案2】:

      您的方法存在几个问题:

      1. 正如其他人所解释的,您不能只拥有Set&lt;long&gt; Set&lt;Long&gt;装箱 long,请参阅Java 中的自动装箱),并且您不能使用addAll 方法将Long[] 的所有元素添加到Set&lt;Long&gt;

      2. 由于您必须保持数字的顺序,将所有值一次添加到一个集合中没有帮助。这将过滤掉重复项,但您会丢失排序。

      3. 由于输入数组已经排序,实际上不需要任何额外的数据结构来删除重复项。

      这是一种O(n) 技术,用于在数组的开头排列唯一值,然后制作数组的有效副本,切断不再需要的数组结尾部分:

      long[] noDups(long[] nums) {
          if (nums.length == 0) return nums;
      
          int pos = 1;
          for (int j = 1; j < nums.length; j++) {
              if (nums[j - 1] != nums[j]) {
                  nums[pos++] = nums[j];
              }
          }
      
          return Arrays.copyOf(nums, pos);
      }
      

      【讨论】:

        【解决方案3】:

        如果您的数组已排序,则不需要嵌套的 for 循环。您应该能够遍历数组一次,并且仅在它与前一个不同时添加该项目。

        List<Long> newList = new ArrayList<Long>();
        for(Long l : target) {       
           if(newList.isEmpty() || !l.equals(newList.get(newList.size()-1))) {
              newList.add(l); 
           }
        }
        

        newList 应该包含所有不重复的条目。

        我没有方便的编译器来测试这个,但希望它是有意义的。

        【讨论】:

          【解决方案4】:

          您不能以您尝试的方式混合原语和包装器 - 特别是,Collections.addAll 在这种情况下只会接受 Long[],而不是 long[]

          接受你需要做一些循环来来回转换。您需要遍历数组并将元素一一添加到Set,然后创建一个原始数组并遍历集合以将元素放入其中。

          (或者您现在可以在任何使用long[] 的地方使用Long[],但这会效率低下,我会避免使用它。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多