【问题标题】:How can I tell if the elements in an Array List are same or different?如何判断数组列表中的元素是相同还是不同?
【发布时间】:2019-02-16 11:48:37
【问题描述】:

我正在尝试验证数组列表中的所有元素是否相同。这是我的代码:

ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(2,2,4,2));
for (int z = 0; z < arr.size(); z++) {          
    if(!arr.get(z++).equals(arr.get(z--))) {
        System.out.println("same"); 
    }else {
        System.out.println("differnt");         
    }
}

【问题讨论】:

  • 是否有必要知道元素的所有组合?否则,只需选择任何元素(例如第一个元素)并进行一次迭代,检查所有元素是否与选择的元素相同。如果是这样,那么所有元素都是相同的。
  • 你知道z++z--实际上是在修改z吗?这段代码读起来超级复杂,我强烈建议不要以任何聪明的方式使用++--,它容易出错并且会使读者感到困惑。如果您只需要下一个或上一个元素,请执行get(z + 1)get(z - 1),这不会修改z
  • 您的问题缺少详细信息。你至少应该给出一个清晰的例子,当前的输出和期望的输出。请阅读minimal reproducible examplehelp centerHow to Ask,谢谢。在当前状态下,它的质量很差,因此可能会收到反对票,甚至接近票数。

标签: java arrays arraylist


【解决方案1】:

将元素放入Set。如果结果集的大小为 1,则所有元素都相同。一行代码,没有循环,没有索引,适用于每个集合:

boolean allTheSame = new HashSet<Integer>(list).size() == 1;
System.out.println(allTheSame ? "same" : "different");

(已编辑:)

可能值得注意的是,如果列表很大,并且可能包含许多不同的元素,那么构造一个Set 会产生一些可能的内存开销避免,如果需要的话。在这种情况下,您将遍历列表并将所有元素与第一个元素进行比较。 但是您应该检查元素是否与== 相同。相反,您应该使用他们的equals 方法比较它们,或者,如果您想处理null 条目,请使用Objects#equals

answer by Zabuza 中给出了如何有效且通用地解决此问题的示例

【讨论】:

  • 根据列表实现,使用get(...) 可能效率很低。相反,请使用 Iterator,例如使用增强的 for 循环。
  • @Zabuza 这是一个有效的观点。我有点仓促地在“编辑”中添加了代码。在实践中,使用泛型和Iterator 或增强的for 循环的解决方案会更合适。所以我再次编辑,只是指出了这个替代方案背后的原因,并链接到你的代码答案。
  • 谢谢,但我需要字符串格式的输出,如果还要寻找组合会更好
【解决方案2】:

对此有多种解决方案。


与其他人比较

您只需选择任何元素(例如第一个元素),然后将其与所有其他元素进行比较。一个简单的循环就足够了:

public static <E> areElementsEquals(List<E> list) {
    // Edge cases
    if (list == null || list.size() <= 1) {
        return true;
    }

    // Pick any element
    E any = list.get(0);
    // Compare against others
    for (E other : list) {
        // Use Objects#equals for null-safety
        if (!Objects.equals(any, other)) {
            return false;
        }
    }
    return true;
}

或 Stream-API 版本:

return list.stream()
    .allMatch(other -> Objects.equals(any, other));

如果您检查了any 不是null,您还可以使用方法参考:

return list.stream()
    .allMatch(any::equals);

设置

集合没有重复项。您可以将所有元素放入Set 并检查大小是否为1,然后所有其他元素都是重复的。

return new HashSet<>(list).size() == 1;

虽然这段代码非常紧凑,但我更喜欢更直接的迭代解决方案。它更具可读性,也更高效,因为它没有设置集合的额外开销。

【讨论】:

    【解决方案3】:

    您只需将第一项与所有其他项进行比较:

    int a = arr.get(0);
    boolean allSame = true;
    for (int z = 1; z < arr.size(); z++) {
        allSame = (a == arr.get(z));
        if (!allSame) break;
    }
    
    if (allSame)
        System.out.println("Same");
    else
        System.out.println("Different");
    

    【讨论】:

    • 需要添加 0-size 列表检查,但总的来说这是完成此任务的正确方法
    • @amseager 为什么要0-size list check?第一项已存储在a
    • 我想他想指出,如果列表的大小为 0arr.get(0) 将抛出 IndexOutOfBoundsException。 (一般来说,如果列表包含 null 条目,由于自动拆箱,代码将抛出 NullPointerException
    • @Marco13 上面的代码是基于 OP 的样本数据(4 个整数的列表)。更通用的解决方案应该包括更多条件,例如如果列表为空,结果是什么?,或者如果列表被空值填充,结果是什么?跨度>
    • 当然,我只是想解释一下 amseager 的评论可能指的是什么。
    【解决方案4】:

    。 . .你的代码有效吗?你得到什么样的输出?你有任何例外吗? 不要将您的列表声明为 ArrayList;将其声明为列表。不要调用 List arr; 它不是数组。称它为numbers 或类似的名称。 为什么你在第 3 行有爆炸符号/非运算符?我认为那不应该在那里。 如果您考虑可用的不同类型的集合/数据结构,您可以阅读 here,您会发现一个集合类型,其 size() 方法会告诉您有多少不同的元素。

    【讨论】:

      【解决方案5】:

      您只需将当前元素与下一个元素进行比较,如果它们不同,则意味着您并非所有元素都相同:

      for(int i = 0; i < list.size() - 1; i++) {
              if (list.get(i) != list.get(i + 1)) {
                  return false; // elements are different
              }
          }
      
      return true; // all element are the same
      

      【讨论】:

      • 当列表包含大于 128 的整数值时,这将返回 false。尝试使用 1000 之类的元素。您应该将引用与!= 进行比较。您应该改用equals,以便轻松处理null 条目,最好使用Objects#equals。除此之外,其他答案中还有更好的选择。
      【解决方案6】:

      试试这个:

      String first = arr.get(0);
      boolean allTheSame = true;
      if (arr.size() > 1) {
          for (int z = 1; z < arr.size(); z++) {
              if (!arr.get(z).equals(first)) {
                  allTheSame = false;
                  break;
              }
          }
      }
      

      【讨论】:

        【解决方案7】:

        一种方法使用BitSet判断列表中的所有元素是否相同,它需要更少的内存并且运行速度更快。

        public static boolean areAllElementsSame(List<Integer> numbers) {
            BitSet set = new BitSet();
            numbers.forEach(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) {
                    set.set(integer);
                }
            });
            return set.cardinality() == 1;
        }
        

        这个方法也可以用来计算有多少不同的元素。

        【讨论】:

          【解决方案8】:

          same 是一个存储我们想要的结果的标志。
          uv 是均匀性变量。
          Object 是您存储在列表(arraylist)中的对象的类型

          import java.util.*; 
          class Main{
              public static void main(String args[]){
                  ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(2,2,2,2));
                  boolean same=true;
                  Object uv=arr.get(0);
                  for (Object i: arr){
                      if(!i.equals(uv)){
                          same=false;
                          break;
                      }   
                  }
                  System.out.print("Result:"+same);
              } 
          }
          

          【讨论】:

            【解决方案9】:

            您必须检查每个元素,如果以后索引上的所有元素都与那个相同或不同。 你可以使用这样的嵌套循环来做到这一点:

            public static void main(String[] args) {
                // write your code here
                    ArrayList<Integer> arr = new ArrayList<Integer>(Arrays.asList(2,2,4,2));
                    boolean result=true;
                    for (int i = 0; i < arr.size(); i++) {
                        for (int j=i; j<arr.size(); j++){
                            if (!arr.get(i).equals(arr.get(j))){
                                result=false;
                            }
                        }
                    }
                    System.out.println(result);
                } 
            

            第二个循环从 j=i 开始,一直到数组的右端,因为您不需要检查该索引的左侧,因为它已经在之前的迭代中检查过,result 已经已更新为false

            【讨论】:

            • 不必要的 O(n2) 复杂度。您可以像@forpas 在他的回答中所做的那样使用 O(n) 来做到这一点
            • @amseager 我同意,但我不认为时间复杂度是手头的真正问题,只要提问者理解答案。
            • Arrays.asList(222,222,222)试试这个。它将打印false。您应该将引用与!= 进行比较。
            【解决方案10】:

            如果要确保列表至少包含两个不同的元素,则必须“遍历”数组一次:将第一个元素与所有其他元素进行比较,并在第一个不匹配时停止。不匹配时:并非所有元素都相同,否则它们都相同!

            但最初的问题有点不清楚。如果要确定数组中是否有 no 两个相等的元素,则必须将所有条目与所有其他条目进行比较!然后您需要两个循环:您按顺序选择所有元素,将它们与所有其他元素进行比较(分别与以下所有元素进行比较:您已经将插槽 1 与所有其他插槽进行了比较,因此您只需将插槽 2 与 slot3 进行比较......直到结束)。

            另一种方法是使用 Set 实现,例如 HashSet!集合具有唯一的成员。所以当你把你的列表变成一个集合,并且集合的条目比列表少时,你知道列表包含重复项。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-09-09
              • 2014-01-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多