一系列独特的元素?

时间:2013-02-01 22:35:00

标签: java arrays unique

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

这是:

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

将其转换为这样的结果数组,保留原始顺序:

   {5,1,2,3,4} 

6 个答案:

答案 0 :(得分:24)

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

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

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

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

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

set.toArray()

如果要维护订单,请使用 LinkedHashSet ;如果要对其进行排序,请使用 TreeSet

答案 1 :(得分:3)

两个选项

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

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

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

答案 2 :(得分:1)

假设一个对象数组:

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替换为您的Array类。

答案 3 :(得分:0)

以下是2个想法:

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

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

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

<块引用>

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

    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 + '}';
}
}