给定一个像下面这样的数组,我想知道是否有一种简单的方法可以将此数组转换为仅具有唯一值的数组?
这是给定的:
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();
最简单的方法是从数组创建集合。
Integer[] array = ...
Set<Integer> set = new LinkedHashSet<Integer>(Arrays.asList(array ));
然后您可以使用以下方法检索数组:
set.toArray()
如果要保持顺序,请使用LinkedHashSet ;如果要对其进行排序,请使用TreeSet。
两种选择
保留计数和元素的映射,最后只使用计数为 1 的元素。(需要额外的存储空间,但速度更快)
对数组进行排序,当您在数组中移动时,仅使用不重复的数组。
不需要额外的空间,但将是 O(n lg(n))
假设一个对象数组:
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
为您的数组类。
这里有2个想法:
将所有项目添加到 Set,或使用具有数组作为参数的构造函数创建一个(HashSet
或TreeSet
,取决于您想要的时间复杂度)。然后,对于集合中的每个元素,将其删除,将其添加到新数组的下一个打开位置,该位置是集合的大小。
对数组进行排序。将索引 0 处的对象添加到ArrayList
. 从索引 1 开始并转到 index length - 1
。如果当前元素不等于前一个索引处的元素,则将其添加到ArrayList
. 如有必要,将其更改ArrayList
为数组。
如果你想合并两个不重复的列表,那么试试这个,它对我有用。
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 + '}';
}
}
(转贴: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 }));
}