Java 为什么自定义实例的ArrayList上的.contains方法有效?
我一直在为工作开发一个小应用程序,但我遇到了一些我无法理解的事情 在下面的代码中,我有一个名为“Product”的自定义类的ArrayList,其中包含“String”类型的数据。我在此ArrayList上使用.contains方法来确保它不包含特定的字符串 我的IDE警告我“对java.util.Collections.contains的可疑调用:给定对象不能包含字符串实例(预期产品)” 我完全理解上面的信息,因为我正在比较两种不同的类型,那么它如何能够正确地进行评估呢?我认为这一定是因为'Product'类包含我想要比较的数据,它默认在Product类上使用toString方法(我在类中重写了它),并将其与我想要比较的字符串进行比较 对我来说,这似乎是一种魔术Java 为什么自定义实例的ArrayList上的.contains方法有效?,java,arraylist,Java,Arraylist,我一直在为工作开发一个小应用程序,但我遇到了一些我无法理解的事情 在下面的代码中,我有一个名为“Product”的自定义类的ArrayList,其中包含“String”类型的数据。我在此ArrayList上使用.contains方法来确保它不包含特定的字符串 我的IDE警告我“对java.util.Collections.contains的可疑调用:给定对象不能包含字符串实例(预期产品)” 我完全理解上面的信息,因为我正在比较两种不同的类型,那么它如何能够正确地进行评估呢?我认为这一定是因为'P
private void createOrderListing(List<String[]> orderList)
{
//For each line of the order list file
for(String[] s : orderList)
{
if(s.length >= 28) //OrderLine should be of this length
{
if (!s[0].equalsIgnoreCase("ProductCode") && !s[0].isEmpty()) //Makes sure we're not including headers
{
//How does this bit work?
if(!productListing.contains(s[0]))
{
OrderLine order = new OrderLine();
//References product code of Product against Order Line, if match, then pack sizes and other basic fields ammended as appropriate
boolean productFound = false;
for (Product p : productListing)
{
if (s[0].contentEquals(p.getProductCode()))
{
order.initialAmendOrderLine(p.getProductCode(), p.getProductName(), p.getPackSize(), p.getProductType());
productFound = true;
}
}
if(productFound)
{
order.setOrderValues(s);
orderListing.add(order);
}
}
//System.out.println("\nOrder Product is: " + order.getProductName()+ "\nOrder Pack Size is: " + order.getInternalPackSize());
}
}
}
}
private void createOrderList(列表orderList)
{
//对于订单列表文件的每一行
对于(字符串[]s:orderList)
{
如果(s.length>=28)//订单行应为此长度
{
如果(!s[0].equalsIgnoreCase(“ProductCode”)和(&!s[0].isEmpty())//确保不包含头
{
//这个钻头是怎么工作的?
如果(!productListing.contains(s[0]))
{
订单行订单=新订单行();
//根据订单行参考产品的产品代码,如果匹配,则根据需要添加包装尺寸和其他基本字段
布尔productFound=false;
for(产品p:productListing)
{
如果(s[0].contentEquals(p.getProductCode()))
{
order.initialAmendOrderLine(p.getProductCode()、p.getProductName()、p.getPackSize()、p.getProductType());
productFound=true;
}
}
如果(找到产品)
{
order.setOrderValues;
添加(订单);
}
}
//System.out.println(“\nOrder产品为:“+order.getProductName()+”\nOrder包装尺寸为:“+order.getInternalPackSize());
}
}
}
}
更新
正如注释中所指出的那样,这种方法之所以有效,是因为块始终为true(.contains方法始终为false,而!将其反转,因此为true)。很抱歉造成混淆,并指出我的粗心。因为包含equals实现上的中继,当您这样做时
if(!productListing.contains(s[0]))
您正在询问字符串数组列表是否包含字符串
因为类型不同,所以总是返回false,这根本不起作用,因为您的条件总是返回false
productList
是一个产品
对象的列表。然而,您会询问列表是否包含一个特定的字符串对象,而不应该发生
您应该做的是检查您的产品#getProductCode
是否等于您的特定字符串。这可以通过以下方法实现:
这个代码是做什么的?它检查所有产品
元素,以找到一个myStringData
属性与您正在比较的字符串
相等的元素。以下是我在OpenJDK中的包含方法的实现:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
如果Product
的equals()
方法使用String
参数比较equals,则contains()
方法可以工作。它不应该这样做,因为这在技术上违反了equals()
的约定,但它可以这样做。哪种类型是productListing?正如你所说,我假设ListproductListing是一种List@aliwaii将信息添加到您的question@KlitosKyriacou您是正确的,该块从未跳过。不幸的是,当我添加此部分时,代码总体上运行得非常好,而之前不是这样,这意味着我假设它在没有解释原因的情况下纠正了问题。如果Product.equals()
也检查String
参数,则不会返回false。s[0]是一个字符串,不是一个数组productListing
是List
@ΦXocę웃Пepeúpaツ productListing可能是一个产品列表,而不是一个字符串列表可能你和我对OP问题的解释不同。你(正确地)回答了如何修复它;但我想他会问为什么它看起来已经起作用了(我怀疑答案是OP误解了结果)。@KlitosKyriacou在标题中说它在哪里起作用了。在对.contains()的调用上方的注释中,@KlitosKyriacou确实如此。
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
public boolean contains(List<Product> products, String yourStringValue) {
for (Product p : products) {
if(p.getProductCode().equals(yourStringValue)){
return true;
}
}
return false;
}