【问题标题】:Using Contains for objects in List collection对 List 集合中的对象使用 Contains
【发布时间】:2019-03-19 02:55:40
【问题描述】:

我正在尝试使用 Contains 方法在 List 集合中按他的名字查找一个对象,但不知何故,它不起作用。我应该如何使用它?

这就是我尝试使用它的方式

CandyDao.getAllCandys().contains("Caramel")

但它找不到我需要的对象。

CandyDao.java

public class CandyDao {
  private List<Candy> candys = Arrays.asList(new Candy("Caramel", 3, false),
          new Candy("Marmelade", 2, true));

  public List<Candy> getAllCandys(){
    return candys;
  }
}

Candy.java

  public class Candy {
  private String name;
  private float price;
  private boolean InStock;

  public Candy() {
  }

  public Candy(String name, float price, boolean InStock) {
    setName(name);
    setPrice(price);
    setInStock(InStock);
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public float getPrice() {
    return price;
  }

  public void setPrice(float price) {
    this.price = price;
  }

  public boolean getInStock() {
    return InStock;
  }

  public void setInStock(boolean InStock) {
    this.InStock = InStock;
  }
}

【问题讨论】:

    标签: java list collections contains


    【解决方案1】:

    由于列表包含Candy对象,contains()方法需要Candy对象进行比较,所以不能使用contains("Caramel")

    要检查列表是否包含name"Caramel"Candy 对象,您可以使用Java 8+ Streams 进行搜索:

    CandyDao.getAllCandys().stream().Map(Candy::getName).anyMatch("Caramel"::equals);
    

    等效的非流版本是:

    boolean hasCaramel = false;
    for (Candy candy : CandyDao.getAllCandys()) {
        if ("Caramel".equals(candy.getName())) {
            hasCaramel = true;
            break;
        }
    }
    

    【讨论】:

      【解决方案2】:

      覆盖equals & hashcode 方法,如下所示:

      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
          Candy candy = (Candy) o;
          return Objects.equals(name, candy.name);
      }
      
      @Override
      public int hashCode() {
          return Objects.hash(name);
      }
      

      现在,由于 equals 函数只检查 Candy 对象的名称是否相等,所以以下应该可以工作:

      CandyDao.getAllCandys().contains(new Candy("Caramel", 0, true)) .   //2nd & 3rd arg of Candy constructor are inessential/dummy
      

      【讨论】:

        【解决方案3】:

        你应该重写Candy中的Object#equals方法,如下所示:

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof Candy)) {
                return false;
            }
        
            Candy that = (Candy) o;
        
            return Objects.equals(that.getName(), this.getName());
        }
        

        覆盖后,如果名称匹配,List#contains 应返回 true

        【讨论】:

        • 那仍然不会让candy.equals("Caramel") 返回真。
        • 同意,他应该使用名称为“Caramel”的糖果对象,而不是使用字符串。
        • 喜欢answer by Pankaj Singhal 节目。
        【解决方案4】:

        getAllCandys() 方法返回Candyobjects 的列表。您应该查看列表中每个元素的nameproperty。所以ccandyslist的一个元素。使用c.getName().contains("Caramel") 查找"Caramel"

        for(Candy c : candys) {
                    System.out.println(c.getName() + " contains? " + c.getName().contains("Caramel"));
                }
        

        【讨论】:

        • list.contains("Caramel") 是在列表中搜索与参数等于的对象,即c.getName().equals("Caramel"),而不是c.getName().contains("Caramel")
        • 是的,你是对的,我也知道其中的区别。但我误解了这个问题。
        猜你喜欢
        • 1970-01-01
        • 2013-04-14
        • 1970-01-01
        • 1970-01-01
        • 2021-08-28
        • 2017-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多