Java 有人能解释一下如何使用indexOf、lastIndexOf删除ArrayList中的重复项吗

Java 有人能解释一下如何使用indexOf、lastIndexOf删除ArrayList中的重复项吗,java,arraylist,Java,Arraylist,我有这段代码,我无法理解代码是如何工作的,它是如何用indexOf和lastIndexOf删除重复的 ArrayList<String> lst = new ArrayList<String>(); lst.add("ABC"); lst.add("ABC"); lst.add("ABCD"); lst.add("ABCD"); lst.add("ABCE"); System.out.println("Duplicates List "+lst); Object[]

我有这段代码,我无法理解代码是如何工作的,它是如何用indexOf和lastIndexOf删除重复的

ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");

System.out.println("Duplicates List "+lst);

Object[] st = lst.toArray();
for (Object s : st) {
    if (lst.indexOf(s) != lst.lastIndexOf(s)) {
        lst.remove(lst.lastIndexOf(s));
    }
}

System.out.println("Distinct List "+lst);
ArrayList lst=new ArrayList();
第1条添加(“ABC”);
第1条添加(“ABC”);
第1条添加(“ABCD”);
第1条添加(“ABCD”);
第1条添加(“ABCE”);
系统输出打印项次(“副本列表”+lst);
对象[]st=lst.toArray();
用于(对象s:st){
如果(第一个索引of(s)!=第一个最后索引of(s)){
第一次移除(第一次移除);
}
}
System.out.println(“不同列表”+lst);

试着在那里多放一些打印语句,我想你自己就能看到了

    for (Object s : st) {
        System.out.println(s);
        System.out.println(lst.indexOf(s));
        System.out.println(lst.lastIndexOf(s));

        if (lst.indexOf(s) != lst.lastIndexOf(s)) {
            lst.remove(lst.lastIndexOf(s));
        }

    }

试着在那里多放一些打印语句,我想你自己就能看到了

    for (Object s : st) {
        System.out.println(s);
        System.out.println(lst.indexOf(s));
        System.out.println(lst.lastIndexOf(s));

        if (lst.indexOf(s) != lst.lastIndexOf(s)) {
            lst.remove(lst.lastIndexOf(s));
        }

    }
它如何使用indexOf和lastIndexOf删除重复项

上述代码获取列表中第一次出现的
s
(如果它以其他方式存在
-1
)的索引,也获取列表中最后一次出现的
s
(如果它以其他方式存在
-1
)的索引,如果两个索引都相同,那么就没有重复,如果它们不相同,那么我们就找到了一个重复的索引,从而将其从列表中删除

根据您当前正在处理的代码,我们可以确认字符串
“ABC”
在集合中出现两次,一个在索引
0
处,另一个在索引
1
处,因此当
if
语句检查这一点时,我们可以保证控件将进入
if
语句内部,因为它们不是相同的索引(意味着字符串
s
至少出现两次),同样的字符串
“ABCD”
在列表中的索引
1
2
处出现两次(注意,此时上次出现的
“ABC”
已从列表中删除,因此
“ABC”
占据索引
1
的位置,这是由于列表本身的大小调整的性质)意思控制将再次进入
if
块,因为它们不是相同的索引

最后,最后一次出现的
s
将从列表中删除,并对循环的每次迭代重复相同的过程

有更有效的方法,您可以,您应该研究它,因为它可以提高性能时间

它如何使用indexOf和lastIndexOf删除重复项

上述代码获取列表中第一次出现的
s
(如果它以其他方式存在
-1
)的索引,也获取列表中最后一次出现的
s
(如果它以其他方式存在
-1
)的索引,如果两个索引都相同,那么就没有重复,如果它们不相同,那么我们就找到了一个重复的索引,从而将其从列表中删除

根据您当前正在处理的代码,我们可以确认字符串
“ABC”
在集合中出现两次,一个在索引
0
处,另一个在索引
1
处,因此当
if
语句检查这一点时,我们可以保证控件将进入
if
语句内部,因为它们不是相同的索引(意味着字符串
s
至少出现两次),同样的字符串
“ABCD”
在列表中的索引
1
2
处出现两次(注意,此时上次出现的
“ABC”
已从列表中删除,因此
“ABC”
占据索引
1
的位置,这是由于列表本身的大小调整的性质)意思控制将再次进入
if
块,因为它们不是相同的索引

最后,最后一次出现的
s
将从列表中删除,并对循环的每次迭代重复相同的过程

有更有效的方法可以使用,您应该研究它,因为它可以提高性能时间。

这是一种非常笨拙(即效率低下)的方法1

它是如何工作的

那么这个谓词,

  lst.indexOf(s) != lst.lastIndexOf(s)
正在测试列表中是否有两个(或更多)的
s
实例。逻辑是,如果列表中第一个
s
和最后一个
s
的位置不同,则必须至少有两个。然后我们删除最后一个实例

因为我们对原始列表中的每个字符串都这样做,所以如果列表中有给定字符串的M个实例,那么该测试将对该字符串执行M次,并将成功M-1次,从而删除这些实例中的M-1。最后,每个不同字符串只剩下一个实例;i、 e.没有重复


1-它是
O(N^2)
并且可以使用
O(N)
临时空间消除
O(N)
中的重复项。一般做法如下:

  • 创建一个临时数组来保存列表内容,并创建一个
    哈希集
  • 对于原始列表中的每个
    s
    • 如果
      s
      不在集合中:
      • 将其添加到集合中,然后
      • 将其添加到临时数组中
  • 清除原始列表
  • 重新添加临时数组中的所有元素
  • 这是一种相当笨拙(即效率低下)的方法1

    它是如何工作的

    那么这个谓词,

      lst.indexOf(s) != lst.lastIndexOf(s)
    
    正在测试列表中是否有两个(或更多)的
    s
    实例。逻辑是,如果列表中第一个
    s
    和最后一个
    s
    的位置不同,则必须至少有两个。然后我们删除最后一个实例

    因为我们对原始列表中的每个字符串都这样做,所以如果列表中有给定字符串的M个实例,那么该测试将对该字符串执行M次,并将成功M-1次,从而删除这些实例中的M-1。在