ArrayList去重问题的相关问答

huangapple go评论77阅读模式
英文:

ArrayList Deduplication Problem Questions

问题

我对从ArrayList中移除重复数据很感兴趣。

ArrayList<String> a = new ArrayList<>();
ArrayList<String> b = new ArrayList<>();

a.add("0");
a.add("1");
a.add("2");
a.add("3");
a.add("4");
a.add("4");
a.add("1");

b.add("5");
b.add("6");
b.add("7");
b.add("8");
b.add("9");
b.add("10");
b.add("11");

for (int i = 0; i < a.size(); i++) {     
    for (int j = 0; j < a.size(); j++) {
            
        if (a.get(i).equals(a.get(j))) {
    
            a.remove(j);
            b.remove(j);
        }
    }
}

a中移除重复的值,我还想同时移除b中相同索引位置的值。
这种方法的问题在于ab的大小不断变小。

有没有更好的方法?

英文:

I'm curious about removing duplicate data from an ArrayList.

Arraylist&lt;String&gt; a = new ArrayList&lt;&gt;();
Arraylist&lt;String&gt; b = new ArrayList&lt;&gt;();
    
a.add(&quot;0&quot;);
a.add(&quot;1&quot;);
a.add(&quot;2&quot;);
a.add(&quot;3&quot;);
a.add(&quot;4&quot;);
a.add(&quot;4&quot;);
a.add(&quot;1&quot;);
    
b.add(&quot;5&quot;);
b.add(&quot;6&quot;);
b.add(&quot;7&quot;);
b.add(&quot;8&quot;);
b.add(&quot;9&quot;);
b.add(&quot;10&quot;);
b.add(&quot;11&quot;);
    
for (int i = 0; i &lt; a.size(); i++ {     
    for (int j = 0; j &lt; a.size(); j++) {
            
        if (a.get(i).equals(a.get(j)) {
    
            a.remove(j);
            b.remove(j);
        }
    }
}

Duplicate values in a must be removed. I also want to remove values at the same index number in b.
The problem with this is that the size of a and b keeps getting smaller

Is there any good way?

答案1

得分: 0

从我的理解中,你试图找到重复的值以便移除它,获取它在数组a中的索引,然后在数组b中移除该索引处的值。一个大问题是,你在尝试寻找重复值的同时修改了数组AS,这可能会引起许多问题。此外,数组a变小(b也是如此)的原因是因为以下代码:

 a.remove(j);
 b.remove(j);

使用.remove()会调整ArrayList a和b的大小。你可以保留数组的顺序和大小,方法是在移除重复值后,跟踪你已经移除重复值的次数,并在移除后再次添加空字符串。

int charPos = 0;
for(int i = 0; i < a.size(); i++) {
   
  for(int j = 0; j < a.size(); j++) {
        
        if(a.get(i).equals(a.get(j))){

             a.remove(j);
             b.remove(j);
             charPos++;
        }

   }
}

for(int i = 0; i < charPos; i++) {
        a.add("");
        b.add("");
}

对于你所提供的示例,请进一步澄清你所允许的操作和限制,以便更好地回答你的问题。目前问题的范围还不够明确。如果可能,请为你给出的示例提供期望的输出结果。

英文:

From my understanding, you are trying to find the duplicate value to remove it, get its index in and from a, and then remove the value in b at that index. One big problem is that you are modifying the array AS you are trying to find the duplicated value this can cause a lot of problems. Moreover, the cause of a getting smaller (so is b) is because of

 a.remove(j);
 b.remove(j);

with the .remove() it will resize the ArrayList a and b. A way you can preserve the order and size of the array is to keep track of how many times you have removed the duplicate values and add the empty string again after the removal.

int charPos = 0;
for(int i = 0; i &lt; a.size(); i++ {
   
  for(int j = 0; j &lt; a.size(); j++) {
        
        if(a.get(i).equals(a.get(j)){

             a.remove(j);
             b.remove(j);
             charPos++;
        }

   }
}

for(int i = 0; i &lt; charPos; i++) {
        a.add(&quot;&quot;);
        b.add(&quot;&quot;);
}

Your question definitely needs further clarification on what you're allowed to do and what not. It's very boarded right now. If possible please provide your expected output for the example you have given.

答案2

得分: 0

一如既往,在编程中可以有许多实现相同结果的方式...然而嵌套循环通常不是所期望的。另外,正如你注意到的那样,你不能在迭代ArrayList时从中删除元素。实现你想要的结果且性能更佳的一种方式如下:

(我没有测试过,但在我的脑海中逻辑是有意义的...至少会给你一些思路)

ArrayList<String> a = // 初始化你的数组
ArrayList<String> b = // 初始化你的数组
Map<String, Integer> m = new HashMap<>();

// 为'a'中的每个成员分配一个计数变量
for (String s : a) {
    Integer count = m.get(s);
    m.put(s, count == null ? 1 : count + 1);
}

// 找出'a'中有重复的元素,然后...
m.forEach((key, value) -> {
    // 如果有重复...
    if (value > 1) {
        // a) 获取索引并从'b'中移除
        b.remove(a.indexOf(key));
        // b) 从'a'中移除
        a.remove(key);
    }
});
英文:

As always, there are many ways of achieving the same end result in programming... however nested loops are never to be desired. Also, you can not iterate over an ArrayList while removing elements from it, as you noticed. One way of achieving the result you want + better performance would be to do as follows:

(I didn't test it, but the logic makes sense inside my head... at least will give you some ideas)

        ArrayList&lt;String&gt; a = // initialize your array
		ArrayList&lt;String&gt; b = // initialize your array
		Map&lt;String, Integer&gt; m = new HashMap&lt;&gt;();

		// assign a count variable to each member of &#39;a&#39;
		for (String s : a) {
			Integer count = m.get(s);
			m.put(s, count == null ? 1 : count + 1);
		}

		// find which elements of &#39;a&#39; have duplicates and...
		m.forEach((key, value) -&gt; {
            // if has duplicates... 
			if (value &gt; 1) {
                // a) get index and remove from &#39;b&#39;
				b.remove(a.indexOf(key));
                // b) remove from &#39;a&#39;
				a.remove(key);
			}
		});

答案3

得分: 0

  1. 仅从一个列表中移除重复项
    要从列表中移除重复项,可以使用Java 8中新增的便利方法 Collection::removeIf。列表中的重复项可以通过条件进行识别:x -> list.indexOf(x) != list.lastIndexOf(x)

因此,以下代码仅从列表 a 中移除所有重复项:

a.removeIf(x -> a.indexOf(x) != a.lastIndexOf(x));
  1. 从列表 a 中删除重复项,并从列表 ab 中删除这些重复项
    最好是根据上述条件将列表 a 中的重复项收集到单独的集合中,然后对两个列表应用 removeAll 方法:
Set<String> dups = a.stream()
                     .filter(x -> a.indexOf(x) != a.lastIndexOf(x))
                     .collect(Collectors.toSet());
a.removeAll(dups);
b.removeAll(dups);
  1. 删除 a 中的重复项,并同时删除 b 中相同索引处的元素
    除了重复项集合 dups 外,还需要收集 a 中的索引列表:
List<Integer> dupIndexes = IntStream.range(0, a.size())
                                    .filter(i -> i < b.size() && dups.contains(a.get(i)))
                                    .boxed()
                                    .collect(Collectors.toList());

然后可以使用逆序(从末尾到开头)删除 b 中的元素:

int index = dupIndexes.size() - 1;
for (int i = b.size() - 1; i >= 0 && index >= 0; i--) {
    int indexToDelete = dupIndexes.get(index);
    // System.out.printf("b[%d] = %s, dupIndexes[%d]=%d%n", i, b.get(i), index, indexToDelete);
    if (i == indexToDelete) {
        b.remove(indexToDelete);
        index--;
    }
}
英文:
  1. Removing duplicates from just one list<br/>
    To remove duplicates from a list, one can use a convenience method Collection::removeIf added in Java 8. The duplicates in the list may be identified by condition: x -&gt; list.indexOf(x) != list.lastIndexOf(x);

Thus, the following code removes all duplicates from just list a:

a.removeIf(x -&gt; a.indexOf(x) != a.lastIndexOf(x));
  1. Deleting the duplicates in list a from both lists a and b<br/>
    It's better to collect the duplicates in list a into separate collection using the above-mentioned condition and then apply removeAll method to both lists:
Set&lt;String&gt; dups = a.stream()
                     .filter(x -&gt; a.indexOf(x) != a.lastIndexOf(x))
                     .collect(Collectors.toSet());
a.removeAll(dups);
b.removeAll(dups);
  1. Delete duplicates in a and the delete elements in b at the same indexes<br/>
    In addition to the set of duplicates dups, a list of indexes in a needs to be collected:
List&lt;Integer&gt; dupIndexes = IntStream.range(0, a.size())
                                    .filter(i-&gt; i &lt; b.size() &amp;&amp; dups.contains(a.get(i)))
                                    .boxed()
                                    .collect(Collectors.toList());

Then the elements in b may be deleted using a reverse order (from end to start):

int index = dupIndexes.size() - 1;
for (int i = b.size() - 1; i &gt;= 0 &amp;&amp; index &gt;= 0; i--) {
    int indexToDelete = dupIndexes.get(index);
    // System.out.printf(&quot;b[%d] = %s, dupIndexes[%d]=%d%n&quot;, i, b.get(i), index, indexToDelete);
    if (i == indexToDelete) {
        b.remove(indexToDelete);
        index--;
    }
}

huangapple
  • 本文由 发表于 2020年9月24日 15:00:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/64041088.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定