一系列独特的元素?
给定一个类似下面的数组,我想知道是否有一种简单的方法可以将此数组转换为仅具有唯一值的数组?
这是给出的:
numbers={5,5,4,3,1,4,5,4,5}
把它变成这样的结果数组,保留原始顺序:
{5,1,2,3,4}
在Java 8中,使用IntStream
获取数组的唯一元素
int[] noDuplicates = IntStream.of(array).distinct().toArray();
最简单的方法是从数组创建set。
Integer[] array = ... Set set = new LinkedHashSet (Arrays.asList(array ));
然后你可以使用以下方法检索数组:
set.toArray()
如果要维护顺序,请使用LinkedHashSet,如果要对其进行排序,请使用TreeSet 。
两种选择
-
保留计数和元素的映射,最后只使用计数为1的那些元素。(需要额外的存储但速度更快)
-
对数组进行排序,当您在数组中移动时,只使用非重复数组。
不需要额外的空间但是O(n lg(n))
假设一个对象数组:
Object[] arr; {...omissis...} List
如果需要,将Object
替换为Array类。
这有两个想法:
-
将所有项添加到Set,或使用具有数组作为参数的构造函数创建一个(
HashSet
或TreeSet
,具体取决于您想要的时间复杂度)。 然后,对于集合中的每个元素,将其删除,将其添加到新数组的下一个打开位置,该数组是该集合的大小。 -
对数组进行排序。 将索引0处的对象添加到
ArrayList
。 从索引1开始,转到索引length - 1
。 如果当前元素不等于前一个索引处的元素,请将其添加到ArrayList
。 如有必要,将ArrayList
更改为数组。
(转发: https ://stackoverflow.com/a/39731584/1520422)
使用Java 8的Stream API,这是一个具有通用Array类型的解决方案:
public static T[] makeUnique(T... values) { return Arrays.stream(values).distinct().toArray(new IntFunction() { @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(); }
最后这是一个小unit testing:
@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 })); }