我有一个像Java一样的地图,
private HashMap<String, Object[][]> theMap;
如果键是一个字符串,并且该条目将成为
行的内容theMap = new HashMap<>();
Object[][] theData = {
{Boolean.FALSE, "Text"}
};
theMap.put("Key1", theData);
沿着这条线的某个地方,我想检查地图中的条目是否等同于另一个对象。目前我这样做,
Object[][] tempData = {
{Boolean.FALSE, "Text"}
};
for(Object key: entries.keySet()) {
if(entries.get(key).equals(tempData)) {
entries.remove(key);
}
}
它没有用。
我更喜欢用对象而不是另一张地图进行比较。我想知道我在这个比较中做错了什么?
答案 0 :(得分:3)
你没有获得相等的原因是数组继承Object#equals()
,这是基于身份,而不是内容的相等。您可以考虑使用java.util.Arrays.deepEquals(Object[], Object[])
进行比较。
这是当前问题的答案。但是,使用Object
的二维数组来保存boolean
和String
是非常糟糕的代码味道,并且表明您需要封装您在数组中放置的内容。
答案 1 :(得分:1)
身份与等效
请确保您了解默认情况下1>------ Build started: Project: TSO.ProductItemList.Model, Configuration: Debug Any CPU ------
1> C:\Program Files\dotnet\dotnet.exe build "C:\projects\tsl\ProductItemList\src\TSO.ProductItemList.Model" --configuration Debug --no-dependencies
1> Project TSO.ProductItemList.Model (.NETStandard,Version=v1.6) will be compiled because project is not safe for incremental compilation. Use --build-profile flag for more information.
1> Compiling TSO.ProductItemList.Model for .NETStandard,Version=v1.6
1> Producing nuget package "TSO.ProductItemList.Model.1.0.2" for TSO.ProductItemList.Model
1> TSO.ProductItemList.Model -> C:\projects\tsl\ProductItemList\src\TSO.ProductItemList.Model\bin\Debug\TSO.ProductItemList.Model.1.0.2.nupkg
1> Producing nuget package "TSO.ProductItemList.Model.1.0.2.symbols" for TSO.ProductItemList.Model
1> TSO.ProductItemList.Model -> C:\projects\tsl\ProductItemList\src\TSO.ProductItemList.Model\bin\Debug\TSO.ProductItemList.Model.1.0.2.symbols.nupkg
1>C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Common.Targets(262,5): error : The system cannot find the file specified
2>------ Build started: Project: TSO.ProductItemList.Client, Configuration: Debug Any CPU ------
2> C:\Program Files\dotnet\dotnet.exe build "C:\projects\tsl\ProductItemList\src\TSO.ProductItemList.Client" --configuration Debug --no-dependencies
2> Project TSO.ProductItemList.Client (.NETStandard,Version=v1.6) will be compiled because project is not safe for incremental compilation. Use --build-profile flag for more information.
2> Compiling TSO.ProductItemList.Client for .NETStandard,Version=v1.6
2> Producing nuget package "TSO.ProductItemList.Client.1.0.1" for TSO.ProductItemList.Client
2> TSO.ProductItemList.Client -> C:\projects\tsl\ProductItemList\src\TSO.ProductItemList.Client\bin\Debug\TSO.ProductItemList.Client.1.0.1.nupkg
2> Producing nuget package "TSO.ProductItemList.Client.1.0.1.symbols" for TSO.ProductItemList.Client
2> TSO.ProductItemList.Client -> C:\projects\tsl\ProductItemList\src\TSO.ProductItemList.Client\bin\Debug\TSO.ProductItemList.Client.1.0.1.symbols.nupkg
2>C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Common.Targets(262,5): error : The system cannot find the file specified
========== Build: 0 succeeded, 2 failed, 0 up-to-date, 0 skipped ==========
equals()
方法检查两个对象引用是否指向同一个对象(标识),这是不是你的代码正在检查。
相反,您的代码正在检查两个对象(您在地图上放置的值)是否具有相同的值(等效)。
以下是关于此主题的两篇文章:
在你的这个特殊问题中,我认为解决方案包括两个步骤:
Object
和tempData
似乎不是一个数组
相同类型的元素(它似乎不是一个二维的
数组)。相反,它包含theData
值,然后是a
Boolean
值。String
在这种情况下,我认为你真的应该思考
通过这个东西是什么,并为它设计一个类(我正在展示
以下示例)equals()
(和hashCode()
)方法
这样您就可以使用equals()
进行等价检查。另请注意,您的IDE(例如Eclipse
)可能会为您生成equals()
和hashCode()
的模板。
示例:(此处我假设您的Boolean
代表一个条件,而您的String
代表一条消息)
class MyRecord {
private Boolean condition;
private String message;
public Boolean getCondition() {
return condition;
}
public void setCondition(Boolean condition) {
this.condition = condition;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((condition == null) ? 0 : condition.hashCode());
result = prime * result
+ ((message == null) ? 0 : message.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyRecord other = (MyRecord) obj;
if (condition == null) {
if (other.condition != null)
return false;
} else if (!condition.equals(other.condition))
return false;
if (message == null) {
if (other.message != null)
return false;
} else if (!message.equals(other.message))
return false;
return true;
}
}