给出一个字符串列表,返回一个包含不同值的列表。换句话说,在返回的列表中,不应多次包含任何值。 (提示:思考集)
distinctValues( ["red", "yellow", "green", "yellow", "blue", "green", "purple"] )
-> ["red", "yellow", "green", "blue", "purple"]
distinctValues( ["jingle", "bells", "jingle", "bells", "jingle", "all", "the", "way"] )
-> ["jingle", "bells", "all", "the", "way"]
我的代码:
public List<String> distinctValues(List<String> stringList) {
Map<String, String> distinctValuesMap = new HashMap<String, String>();
for (int i= 0; i < stringList.size(); i++) {
distinctValuesMap.put(stringList.get(i), stringList.get(i));
}
Set<String>distinctValuesSet = distinctValuesMap.keySet();
List<String>distinctValues = new ArrayList<String>(distinctValuesSet);
System.out.println(distinctValues);
return distinctValues;
}
预期结果:红色,黄色,绿色,蓝色,紫色 我的结果:红色,绿色,蓝色,黄色,紫色
不确定我要去哪里错,但是我尝试了不同的方法,但无法获得预期的结果。
答案 0 :(得分:2)
您丢失了有关插入顺序的信息,因为您使用的是无序集合Set
。插入顺序保留在 LinkedList (及其集合)之类的数据结构中变体 LinkedHashSet 或其地图变体 LinkedHashMap )。
在LinkedList上使用LinkedHashSet或LinkedHashMap的优点是,在插入时,当检查重复项时,在LinkedHashSet或LinkedHashMap中为O(1),而LinkedList为O(n)。
您也可以使用Java 8 stream.distinct()
来实现相同的目的。
以下是几种选择:
public class MyApp {
public static void main(String[] args) {
List myList = Arrays.asList("red", "yellow", "green", "yellow", "blue", "green", "purple");
distinctValuesUsingStreamDistinct(myList).forEach(System.out::println);
System.out.println("==============");
distinctValuesUsingLinkedHashSet(myList).forEach(System.out::println);
}
public static List<String> distinctValuesUsingStreamDistinct(List<String> stringList) {
return stringList.stream().distinct().collect(Collectors.toList());
}
public static List<String> distinctValuesUsingLinkedHashSet(List<String> stringList) {
LinkedHashSet<String> setSortedByInsertionOrder = new LinkedHashSet<String>();
stringList.forEach(str -> setSortedByInsertionOrder.add(str));
return new ArrayList<>(setSortedByInsertionOrder);
}
}
答案 1 :(得分:2)
集合只是一组值。它没有索引,因此没有顺序。当将Set转换为ArrayList时,元素可以按任何顺序排列,并且无法更改它。如果您想保留元素的顺序,可以使用一个名为retainAll()
的ArrayList整洁的小函数。这使您仅保留集合中存在的元素,但保持ArrayList的顺序。这是您的代码,经过略微修改和简化以证明这一点:
public List<String> distinctValues(List<String> stringList) {
Set<String> distinctValuesSet = new HashSet<>(stringList);
List<String> distinctValues = new ArrayList<>(stringList);
distinctValues.retainAll(distinctValuesSet);
return distinctValues;
}
答案 2 :(得分:1)
Stream::distinct
只需使用Java流distinct
即可在保留原始顺序的同时从列表中获取不同的元素列表。
在一行代码中。
List<String> result = list.stream().distinct().collect(Collectors.toList());
或多行。
List<String> result =
list
.stream()
.distinct()
.collect(
Collectors.toList()
)
;