使用equals </string>删除List <string>重复项

时间:2013-10-16 14:06:48

标签: java list duplicates equals

我对Java很新,我一直试图解决以下问题失败。

编写一个Java方法,删除给定列表中的重复项。

假设:

  1. 方法接受类型列表
  2. 返回类型为void
  3. 使用equals()
  4. 确定重复项

    主:

    1. 创建List的瞬间并使用重复的String值
    2. 加载它
    3. 调用removeDuplicates(),传入此列表
    4. 将修改后的列表输出到控制台。
    5. 我可以通过将我的列表传递给新的HashSet并将其复制回来解决问题。 但问题是:

      1. 问题是要求我使用equals()...
      2. 解决问题
      3. 如果返回类型为void,如何在main中输出?
      4. import java.util。*;     公共课题1 {

            public static void main(String[] args) {
        String[] words = {"good","better", "best", "best", "first" , "last", "last", "last", "good"};  
                List<String> list = new ArrayList<String>();  
                for (String s : words) {  
                    list.add(s);  
                }  
                removeDuplicates(list);
            }
            static void removeDuplicates(List<String> array){
                HashSet<String> hs = new HashSet<>();
                hs.addAll(array);
                array.clear();
                array.addAll(hs);
                for (String x : array){ 
                    System.out.println(x);
                }
            }
        }
        
        编辑:嗯,这个可以工作,但是你可以看到我没有使用equals()而且我从我的静态方法打印出来,而不是从main打印出来。 另外,有没有什么方法可以比使用String []更快地填充List?

4 个答案:

答案 0 :(得分:3)

java.util.HashSetObject.equals(Object)的实现中使用Set.add(Object)来确定要插入的元素是唯一的(由不等于另一个元素定义)。 HashSet还具有允许您在O(n)时间内执行重复数据删除过程的优势,以及在O(n^2)时间内将每个元素与每个其他元素进行比较的更天真的方法。

main中的代码将看到修改后的列表,因为List对象是可变的。当方法更改传入参数的状态时,调用代码将看到这些更改。

答案 1 :(得分:2)

  1. removeDuplicates创建一个set,然后遍历输入列表。如果遇到输入列表中的元素(也在集合中),removeDuplicates会从输入列表中删除元素,否则会将元素添加到集合中。
  2. Java是一种逐个引用的语言(sort of)。这意味着,方法removeDuplicates可以修改它收到的List<String> array,并且调用者会在调用removeDuplicates后返回修改后的列表。

答案 2 :(得分:1)

最简单的方法是首先使用Set,根据定义,它不允许重复。

对于您的实际问题,您可以采取以下几种方法:

  • 简单但缓慢的方法:将每个元素A与列表中的每个其他元素N进行比较。如果A.equals(N)删除N.提示:您只需将A与每个其他元素进行比较,因为您已经在A之前检查了每个元素。

  • 更快的方法:使用自然编译器对列表进行排序。现在你不再需要比较每个元素A和N,而只需要比较A和接下来的几个元素。确切地说:直到找到第一个不等于A的元素。在这种情况下,你可以假设没有进一步的A副本(由于排序)并继续将下一个元素作为A。

  • Map方法(快速但需要更多内存):对于放入列表中的每个元素,将相同的元素放入Map中,任何Object作为值。现在你可以查看该元素是否已经存在于地图中,如果是,则它是重复的。

最好的方法是第二种方法,因为排序非常快,你只需要获得每个元素一次,并且没有必要的第二个列表。

编辑:代码中的第二种方法:

static void removeDuplicates(List<String> array) {
  if (array.size() <= 1) {
    return;
  }
  Collections.sort(array);
  final Iterator<String> it = array.iterator();
  String a = it.next(), n;
  while (it.hasNext()) {
    n = it.next();
    if (((a == null) && (n != null))
            || ((a != null) && (a.equals(n) == false))) {
      a = n;
    } else {
      it.remove();
    }
  }
}

答案 3 :(得分:1)

以下是如何在不使用Set而仅使用equals()的情况下执行相同操作(也有点回答有关初始化List的“编辑”问题):

  public static void main(String[] args) {
    List<String> list = new ArrayList<String>(Arrays.asList(new String[] {
        "good", "better", "best", "best", "first", "last", "last", "last",
        "good"}));
    removeDuplicates(list);
    for (String x : list) {
      System.out.println(x);
    }
  }

  static void removeDuplicates(List<String> array) {
    for (int i = 0; i < array.size(); i++) {
      String next = array.get(i);

      // check if this has already appeared before
      for (int j = 0; j < i; j++) {
        // if it has, stop the search and remove it
        if (next.equals(array.get(j))) {
          array.remove(i);
          // decrement i since we just removed the i'th element
          i--;
          // stop the search
          break;
        }
      }
    }
  }

尽管如此,使用HashSet是一个更好的主意,因为已经指出它更有效。

如果你想要HashSet的效率,但仍保留List的顺序,你可以这样做:

  static void removeDuplicates(List<String> array) {
    Set<String> set = new HashSet<String>();

    for (int i = 0; i < array.size(); i++) {
      String next = array.get(i);

      // check if this has already appeared before
      if (!set.add(next)) {
        // if it has then remove it
        array.remove(i);
        // decrement i since we just removed the i'th element
        i--;
      }
    }
  }