我有嵌套的LinkedList,其中包含一些元素。我想从Outter LinkedList中删除重复的内部LinkedList。元素的顺序无关紧要。[Cat,Mouse,Dog]与[Mouse,Cat,Dog]和I相同想要删除他们中的一个。 例如:
假设
[[Cat,Mouse,Dog],[Dog,Mouse,Cat],[Dog,Horse,Cat],[Dog,Tiger,Lion]]
然后我想要像这样输出
[[Cat,Mouse,Dog],[Dog,Horse,Cat],[Dog,Tiger,Lion]]
我试过了。但我想要最佳解决方案...... 我的代码如下
for (int iBoardListCnt = 0; this.roomCombinationsMasterList != null && iBoardListCnt < this.roomCombinationsMasterList.size(); iBoardListCnt++) {
LinkedList<Board> alRoomCombinationList = new LinkedList<>();
alRoomCombinationList = this.roomCombinationsMasterList.get(iBoardListCnt);
ArrayList<String> alTemp = new ArrayList();
for (int icount = 0; icount < alRoomCombinationList.size(); icount++) {
alTemp.add((alRoomCombinationList.get(icount).getRoomDescription() + alRoomCombinationList.get(icount).getDescription()).toString());
}
roomCombinationsMasterList.remove(iBoardListCnt);
Collections.sort(alTemp, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareToIgnoreCase(s2);
}
});
Iterator<LinkedList<Board>> iterator = roomCombinationsMasterList.iterator();
while (iterator.hasNext()) {
ArrayList<String> alTemp1 = new ArrayList<>();
for (Board data : iterator.next()) {
alTemp1.add((data.getRoomDescription() + data.getDescription()).toString());
}
Collections.sort(alTemp1, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareToIgnoreCase(s2);
}
});
if (alTemp.equals(alTemp1)) {
iterator.remove();
continue;
}
}
roomCombinationsMasterList.add(iBoardListCnt, alRoomCombinationList);
}
在这段代码中,我从Nested LinkedList中获取了Fist元素。存储在临时LinkedList中我从main arraylist中删除了该元素。现在我将LinkedList中的下一个元素存储到第二个临时LinkedList中。使用Comparator对LinkedList进行排序并使用equals()方法比较这两个LinkedList。如果两者相同,则使用Iterator删除其中的1个。 请给我最优解决方案。
答案 0 :(得分:4)
有多种方法可以从列表中删除重复的元素。您需要的“最佳”解决方案需要使用适当的数据结构,该结构针对contains
操作进行了优化。在您的情况下,它将是HashSet
。
这个想法是,在遍历原始集合的同时,维护遍历元素集并检查当前元素是否已经遍历。这种方法可以修改原始集合。
List<List<String>> input = new LinkedList<List<String>>(Arrays.asList(
Arrays.asList("Cat", "Mouse", "Dog"),
Arrays.asList("Dog", "Mouse", "Cat"),
Arrays.asList("Dog", "Horse", "Cat"),
Arrays.asList("Dog", "Tiger", "Lion")));
Set<Set<String>> distinctElements = new HashSet<Set<String>>();
for (Iterator<List<String>> iterator = input.iterator(); iterator.hasNext(); ) {
List<String> element = iterator.next();
HashSet<String> elementAsSet = new HashSet<String>(element);
if (!distinctElements.contains(elementAsSet)) {
distinctElements.add(elementAsSet);
} else {
iterator.remove();
}
}
System.out.println(input);
第二个选项是将原始列表列表转换为LinkedHashSet<LinkedHashSet<String>>
。 LinkedHashSet
同时表现得像Set
和List
(实际上,它同时具有这两种数据结构)。因此,它可以在保留元素顺序的同时消除重复,就像您需要的那样。可能它不是你的选择,因为你说你必须保留你的收藏类型,但仍然,这是一个值得考虑的好(和短)选项。
LinkedHashSet<LinkedHashSet<String>> results = new LinkedHashSet<LinkedHashSet<String>>();
for (List<String> strings : input) {
results.add(new LinkedHashSet<>(strings));
}
System.out.println(results);
最后是Java 8的单行代码:
LinkedList<LinkedList<String>> results = input.stream().map(LinkedHashSet::new).distinct()
.map(LinkedList::new).collect(Collectors.toCollection(() -> new LinkedList<LinkedList<String>>()));
如果你不关心返回集合的类型,那么它是更短的版本:
List<List<String>> results = input.stream().map(LinkedHashSet::new).distinct()
.map(LinkedList::new).collect(Collectors.toList());
答案 1 :(得分:2)
import java.util.*;
import static me.test.Test.Animal.*;
public class Test {
public static enum Animal {
Dog,Tiger,Lion,Horse,Cat,Mouse
}
public static void main ( String[] args ) {
List<Animal> list1 = new LinkedList<>(Arrays.asList(Cat,Mouse,Dog));
List<Animal> list2 = new LinkedList<>(Arrays.asList(Dog,Mouse,Cat));
List<Animal> list3 = new LinkedList<>(Arrays.asList(Dog,Horse,Cat));
List<Animal> list4 = new LinkedList<>(Arrays.asList(Dog,Tiger,Lion));
List<List<Animal>> list = new LinkedList<>(Arrays.asList(list1, list2, list3, list4));
Set<List<Animal>> sorted = new LinkedHashSet<>();
for (List<Animal> animals : list) {
List<Animal> arList = new ArrayList<>(animals);
Collections.sort(arList);
sorted.add(new LinkedList<>(arList));
}
for (List<Animal> animals : sorted) {
System.out.println(animals);
}
}
}
算法: 排序单个列表,以便我们可以比较它们。像[cat,dog]和[dog,cat]这样的列表是相同的,但是equals会返回false。现在,只需使用HashSet。 hashCode()方法将遍历每个add上的单个元素以生成hash,然后可以使用它来比较列表。我使用了LinkedHashSet,因此可以恢复原始订单。
答案 2 :(得分:1)
试试这个我创建了一个优化的解决方案,只需要最少的时间。
public class UniqueLinkedList {
public static void main(String[] args) {
List<String> list1 = new LinkedList<>(Arrays.asList("Cat","Mouse","Dog"));
List<String> list2 = new LinkedList<>(Arrays.asList("Dog","Mouse","Cat"));
List<String> list3 = new LinkedList<>(Arrays.asList("Dog","Horse","Cat"));
List<String> list4 = new LinkedList<>(Arrays.asList("Dog","Tiger","Lion"));
List<List<String>> list = new LinkedList<>(Arrays.asList(list1, list2, list3, list4));
boolean flag = false;
boolean matchFlag = true;
for(int i = 0; i < list.size(); i++){
for(int j = i+1; j < list.size(); j++){
if(list.get(i).size() == list.get(j).size()){
matchFlag = true;
for(String str : list.get(i)){
flag = false;
for(String string : list.get(j)){
if(str.equals(string)){
flag = true;
}
}
if(flag == false){
matchFlag = false;
break;
}
}
if(matchFlag){
list.remove(j);
j--;
}
}
}
}
System.out.println(list.size());
for(int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
}
}