【问题标题】:How can I remove the values which are duplicated in the Array?如何删除数组中重复的值?
【发布时间】:2019-10-08 23:58:31
【问题描述】:

我有下面的ArrayList

["P", "a", "y", "P", "a", "l", "I", "n", "d", "i", "a"]

预期结果[y, l, I, n, d, i]

我想删除所有重复项,包括原始值。 例如:“P”是重复的。如果我使用 set,它将删除重复项并显示一个“P”。 我想删除所有的“P”。

我试过下面的代码。但它只有在有字符集的情况下才有效,

ArrayList<Character> unique = new ArrayList<Character>();
for (Character c : b) {
    if (unique.contains(c)) {
        unique.remove(c);
    } else {
        unique.add(c);
    }
}

此代码验证并删除“P”,但不验证“a”。因为 'a' 列出了 3 t

【问题讨论】:

  • 为什么不想使用地图?这是家庭作业吗?这是它的条件吗?因为使用地图来记数是这个问题的自然解决方案。
  • 你可以查看这个帖子stackoverflow.com/questions/27911406/…

标签: java collections


【解决方案1】:

首先计算每个字符的出现次数,然后按出现次数过滤掉(仅出现一次)。

List<Character> input = Arrays.asList('P', 'a', 'y', 'P', 'a', 'l', 'I', 'n', 'd', 'i', 'a');

List<Character> collect = input.stream()
    .collect(Collectors.groupingBy(p -> p, Collectors.counting()))
    .entrySet().stream()
    .filter(e -> e.getValue() == 1)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

System.out.println(collect);

没有流的旧版本可以这样写:

// create Map with count occurence
Map<Character, Integer> countMap = new HashMap<>();
for (Character value : input) {
    if (!countMap.containsKey(value)) {
        countMap.put(value, 1);
    } else {
        countMap.put(value, countMap.get(value) + 1);
    }
}

// filter Map
List<Character> collect = new ArrayList<>();
for (Map.Entry<Character, Integer> value : countMap.entrySet()) {
    if( value.getValue() == 1)  {
        collect.add(value.getKey());
    }
}

System.out.println(collect);

【讨论】:

    【解决方案2】:

    试试这个方法:

    public static void main(String[] args) {
        List<Character> unique = Arrays.asList('P', 'a', 'y', 'P', 'a', 'l', 'I', 'n', 'd', 'i', 'a');
        List<Character> result = unique.stream().filter(i1 -> unique.stream().filter(i2 -> i1.equals(i2)).count() == 1).collect(Collectors.toList());
        System.out.println(result);
    }
    

    输出为:[y, l, I, n, d, i]

    【讨论】:

      【解决方案3】:

      这可能会有所帮助

      import java.util.HashSet;
      import java.util.Iterator;
      import java.util.List;
      import java.util.Set;
      import java.util.stream.Collectors;
      
      public class RemoveDuplicates {
      public static void main(String[] args) {
      
          String string = "PayPalIndia";
      
          List<Character> strings = string.chars().mapToObj(c -> (char) c).collect(Collectors.toList());
          Set<Character> set = new HashSet<>();
      
          Iterator<Character> iterator = strings.iterator();
          Set<Character> invalid = new HashSet<>();
          while (iterator.hasNext()) {
              Character c = iterator.next();
              if (set.contains(c)) {
                  iterator.remove();
                  invalid.add(c);
              } else {
                  set.add(c);
              }
          }
          System.out.println("Duplicate parents");
          invalid.forEach(System.out::print);
          System.out.println();
          strings.removeAll(invalid);
      
          System.out.println("=============");
          System.out.println("After removing Duplicates...");
          strings.forEach(System.out::print);
          System.out.println();
      }
      

      }

      【讨论】:

        【解决方案4】:

        在没有 Java 8 流的情况下可以做到这一点的一种有趣方法是创建一个大小为 128int 数组,该数组将在字符值的索引处保存每次出现的计数。

        例如,如果a 出现3 次,array[97] 将等于3,其中97a 的Ascii 值(我知道技术上不使用ascii)。

        此实现的缺点是它无法处理 ascii 表中前 128 个字符以上的任何其他字符。虽然你可以相应地扩展它。

        这就是它的样子:

        public static void main(String[] args) {
            ArrayList<Character> list = new ArrayList<>();
            list.add(Character.valueOf('P'));
            list.add(Character.valueOf('t'));
            list.add(Character.valueOf('L'));
            list.add(Character.valueOf('L'));
            list.add(Character.valueOf('b'));
            list.add(Character.valueOf('P'));
            list.add(Character.valueOf('c'));
        
        
            int [] lookup = new int[128];
        
            //Build the lookup table
            for (char c : list) {
                lookup[c]++;
            }
        
            //Remove the values that are greater than 1 in the lookup table
            for (int j = 0; j < lookup.length; j++) {
                int count = lookup[j];
                for (int k = 0; k < count && count > 1; k++) {
                    list.remove(Character.valueOf((char) j));
                }
            }
        }
        

        代码基本上分为两个主要部分:

        • 构建查找表。

        • 使用查找表作为参考从列表中删除值。

        现在这显然比使用 MapSet 或使用流的解决方案更复杂,但我认为根据您的要求,您可能也无法使用流。

        【讨论】:

          【解决方案5】:

          试试这个

          ArrayList charsList = new ArrayList(Arrays.asList('P', 'a', 'y', 'P', 'a', 'l', 'I', 'n', 'd' , 'i', 'a'));

          列表 listWithoutDuplicates = charsList.stream().distinct().collect(Collectors.toList());

          【讨论】:

          • 请在发布答案之前努力阅读并理解要求...
          猜你喜欢
          • 2015-09-24
          • 2012-06-05
          • 2011-08-05
          • 2014-07-15
          • 2018-02-13
          • 2020-12-06
          • 2017-08-31
          • 1970-01-01
          • 2011-09-02
          相关资源
          最近更新 更多