【问题标题】:Array of unique elements?独特元素的数组?
【发布时间】:2013-02-01 22:34:59
【问题描述】:

给定一个像下面这样的数组,我想知道是否有一种简单的方法可以将此数组转换为仅具有唯一值的数组?

这是给定的:

   numbers={5,5,4,3,1,4,5,4,5} 

把它变成这样的结果数组,保持原来的顺序:

   {5,1,2,3,4} 

【问题讨论】:

  • 总是排序的吗?是的,有一个简单的方法,但是您尝试过什么?
  • 不,它不是在所有情况下都排序的。
  • @MHZ:结果数组的顺序重要吗?例如。应该保留第一个数组的顺序吗?
  • 没有结果数组的顺序,没关系,只要所有元素都是唯一的。

标签: java arrays unique


【解决方案1】:

在 Java 8 中,使用 IntStream 获取数组的唯一元素

int[] noDuplicates = IntStream.of(array).distinct().toArray();

最简单的方法是从数组中创建集合。

Integer[] array = ...
Set<Integer> set = new LinkedHashSet<Integer>(Arrays.asList(array ));

然后您可以使用以下方法检索数组:

set.toArray()

如果要保持顺序,请使用 LinkedHashSet,如果要对其进行排序,请使用 TreeSet

【讨论】:

  • 我正在处理字符串,但我得到了,HashSet 无法解析为类型。
  • 表示你需要导入HashSet,只需add import java.util.HashSet;你应该考虑使用像Eclipse这样的IDE
【解决方案2】:

两种选择

  1. 保留计数和元素的映射,最后只使用计数为 1 的元素。(需要额外的存储空间,但速度更快)

  2. 对数组进行排序,当您在数组中移动时,仅使用不重复的数组。

不需要额外的空间,但会是 O(n lg(n))

【讨论】:

  • 选项 1 的时间复杂度可能不会更快。如果您对地图使用平衡二叉搜索树,您将获得 lg(N) 操作。如果您使用哈希表,您就是在统一哈希假设下进行操作。
  • 我假设一个哈希表。并且所有标准语言都具有良好的散列函数,或多或少确保 O(1) 插入和检索
  • 好的。我想既然是数字就好了。为 int 制作哈希并不难:)。但是,哈希表的大小很重要,因为您必须循环遍历存储在其中的所有值,即 O(M),其中 M 是哈希表的大小。无论如何,好的,快速的答案,所以+1。
【解决方案3】:

这里有两个想法:

  1. 将所有项目添加到 Set,或使用具有数组作为参数的构造函数创建一个(HashSetTreeSet,具体取决于您想要的时间复杂度)。然后,对于集合中的每个元素,将其删除,将其添加到新数组的下一个打开位置,该位置是集合的大小。

  2. 对数组进行排序。将索引 0 处的对象添加到 ArrayList。从索引 1 开始并转到索引 length - 1。如果当前元素等于前一个索引处的元素,则将其添加到ArrayList。如有必要,将ArrayList 更改为数组。

【讨论】:

    【解决方案4】:

    假设一个对象数组:

    Object[] arr;
    
    {...omissis...}
    
    List<Object> list = new ArrayList<Object>();
    for(Object val: arr) {
      if(!list.contains(val)) {
        list.add(val);
      }
    }
    list.toArray(new Object[0]);
    

    如果需要,将 Object 替换为您的数组类。

    【讨论】:

    • 感谢您的回复。我使用的是数组而不是数组列表。
    • @MHZ 这甚至适用于数组,所以 arr 是一个对象数组,我编辑我的帖子
    • 这是一种非常昂贵的方法,因为list.contains() 会随着列表的增长而线性增加工作量。对于非常大的列表,与数千年的处理时间相比,这可能会有几秒钟的差异......如果您想保持这种方法,最好使用 HashSet 进行包含查找,使用 List 进行结果积累。
    【解决方案5】:

    (转发:https://stackoverflow.com/a/39731584/1520422

    使用 Java 8 的 Stream API,这是一个具有通用 Array 类型的解决方案:

    public static <T> T[] makeUnique(T... values)
    {
        return Arrays.stream(values).distinct().toArray(new IntFunction<T[]>()
        {
    
            @Override
            public T[] apply(int length)
            {
                return (T[]) Array.newInstance(values.getClass().getComponentType(), length);
            }
    
        });
    }
    

    它适用于任何 Object 类型的数组,但不适用于原始数组。

    对于原始数组,它看起来像这样:

    public static int[] makeUnique(int... values)
    {
        return Arrays.stream(values).distinct().toArray();
    }
    

    最后是一个小单元测试:

    @Test
    public void testMakeUnique()
    {
        assertArrayEquals(new String[] { "a", "b", "c" }, makeUnique("a", "b", "c", "b", "a"));
        assertArrayEquals(new Object[] { "a", "b", "c" }, makeUnique(new Object[] { "a", "b", "c", "b", "a" }));
        assertArrayEquals(new Integer[] { 1, 2, 3, 4, 5 }, makeUnique(new Integer[] { 1, 2, 2, 3, 3, 3, 1, 4, 5, 5, 5, 1 }));
        assertArrayEquals(new int[] { 1, 2, 3, 4, 5 }, makeUnique(new int[] { 1, 2, 2, 3, 3, 3, 1, 4, 5, 5, 5, 1 }));
    }
    

    【讨论】:

      【解决方案6】:

      如果你想合并两个不重复的列表,那么试试这个,它对我有用。

          List<Name> list1 = Arrays.asList(new Name("abc", 1), new Name("def", 2), new Name("ghi", 3));
          List<Name> list2 = Arrays.asList(new Name("def", 4), new Name("jkl", 5), new Name("mno", 6));
         
          List<Name> newNameList= new ArrayList<>(Stream.of(list1, list2).flatMap(List::stream)
                  .collect(Collectors.toMap(Name::getName, d -> d, (Name x, Name y) -> x == null ? y : x)).values());
          newNameList.forEach(System.out::println);
      
      
      class Name {
      String name;
      int id;
      
      public Name(String name, int id) {
          this.name = name;
          this.id = id;
      }
      
      public String getName() {
          return name;
      }
      
      @Override
      public String toString() {
          return "Name{" + "name='" + name + '\'' + ", id=" + id + '}';
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多