"contains()" 方法如何真正作用于 List<string>?
How "contains()" method really work on List<string>?
我正在尝试检查两个列表是否包含相同的值,但我无法弄清楚为什么这个特定值会触发我的 FileException
private static void checkFileHeaders(List<ColumnDefinition> columnsDefinitions, ArrayList<String> columnsName) throws FileException {
for (ColumnDefinition cd : columnsDefinitions) {
if(!columnsName.contains(cd.getFieldNameInFile())) {
throw new FileException("Parameter "+cd.getFieldNameInFile() +" missing ");
}
}
}
正如我们在调试器中看到的那样,我的值存在于列表中,它是否与编码有关?它适用于其他值,但不适用于这个特定值。
我知道 contains() 的工作方式与 equals() 类似,所以这里有什么问题
如果我看单个字符:
cd.getFieldNameInFile() : [90, 66, 75, 80, 70, 45, 66, 85, 75, 82, 83]
列名[0] : [-1, -2, 90, 0, 66, 0, 75, 0, 80, 0, 70, 0, 45, 0, 66, 0, 85, 0, 75 , 0, 82, 0, 83, 0]
如何解决这个差异,原因是什么?
它检查每个元素,如果它是 equal()
到您正在测试的元素。意思是,如果两个元素通过 equals()
方法测试,contains()
方法将为他们 return true,如果 equals()
方法 return 为 false,那么 contains()
方法也会如此。
来自 Java 文档:
boolean contains(Object o)
Returns true if this list contains the specified element. More
formally, returns true if and only if this list contains at least one
element e such that (o==null ? e==null : o.equals(e)).
文档Link
https://docs.oracle.com/javase/8/docs/api/java/util/List.html#contains-java.lang.Object-
显然 getFieldNameInFile
不是字符串。所以应该拿 toString
,
private static void checkFileHeaders(List<ColumnDefinition> columnsDefinitions,
List<String> columnsName) throws FileException {
for (ColumnDefinition cd : columnsDefinitions) {
if(!columnsName.contains(cd.getFieldNameInFile().toString()) {
throw new FileException("Parameter "+cd.getFieldNameInFile() +" missing ");
}
}
}
使用流:
private static void checkFileHeaders(List<ColumnDefinition> columnsDefinitions,
Set<String> columnsName) throws FileException {
if (columnsDefinitions.streams
.map(ColumnDefinition::getFieldNameInFile)
.map(Object::toString)
.anyMatch(nm -> !columnsName.contains(nm)) {
throw new FileException("Parameter " + cd.getFieldNameInFile() + " missing ");
}
}
此外ArrayList
它太具体了,使用一个接口,List
因为这个方法可以用于任何类型的列表实现。
而 Set<String>
对于 contains
来说会快得多,例如 HashSet<>
。
我们忽略考虑的是,即使为 class 定义了 equals()
方法,hashCode()
方法仍然需要关心(即使在这里你假设比较字符串可能不是?)。
为什么?
contains
依赖于 equals
并且 equals 与 hashCode
一起工作以判断我们是否在此处谈论引用术语中的同一对象。
根据 equals-hashCode
合同恢复 contains()
工作
More documentation
我正在尝试检查两个列表是否包含相同的值,但我无法弄清楚为什么这个特定值会触发我的 FileException
private static void checkFileHeaders(List<ColumnDefinition> columnsDefinitions, ArrayList<String> columnsName) throws FileException {
for (ColumnDefinition cd : columnsDefinitions) {
if(!columnsName.contains(cd.getFieldNameInFile())) {
throw new FileException("Parameter "+cd.getFieldNameInFile() +" missing ");
}
}
}
正如我们在调试器中看到的那样,我的值存在于列表中,它是否与编码有关?它适用于其他值,但不适用于这个特定值。
我知道 contains() 的工作方式与 equals() 类似,所以这里有什么问题
如果我看单个字符:
cd.getFieldNameInFile() : [90, 66, 75, 80, 70, 45, 66, 85, 75, 82, 83]
列名[0] : [-1, -2, 90, 0, 66, 0, 75, 0, 80, 0, 70, 0, 45, 0, 66, 0, 85, 0, 75 , 0, 82, 0, 83, 0]
如何解决这个差异,原因是什么?
它检查每个元素,如果它是 equal()
到您正在测试的元素。意思是,如果两个元素通过 equals()
方法测试,contains()
方法将为他们 return true,如果 equals()
方法 return 为 false,那么 contains()
方法也会如此。
来自 Java 文档:
boolean contains(Object o)
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
文档Link
https://docs.oracle.com/javase/8/docs/api/java/util/List.html#contains-java.lang.Object-
显然 getFieldNameInFile
不是字符串。所以应该拿 toString
,
private static void checkFileHeaders(List<ColumnDefinition> columnsDefinitions,
List<String> columnsName) throws FileException {
for (ColumnDefinition cd : columnsDefinitions) {
if(!columnsName.contains(cd.getFieldNameInFile().toString()) {
throw new FileException("Parameter "+cd.getFieldNameInFile() +" missing ");
}
}
}
使用流:
private static void checkFileHeaders(List<ColumnDefinition> columnsDefinitions,
Set<String> columnsName) throws FileException {
if (columnsDefinitions.streams
.map(ColumnDefinition::getFieldNameInFile)
.map(Object::toString)
.anyMatch(nm -> !columnsName.contains(nm)) {
throw new FileException("Parameter " + cd.getFieldNameInFile() + " missing ");
}
}
此外ArrayList
它太具体了,使用一个接口,List
因为这个方法可以用于任何类型的列表实现。
而 Set<String>
对于 contains
来说会快得多,例如 HashSet<>
。
我们忽略考虑的是,即使为 class 定义了 equals()
方法,hashCode()
方法仍然需要关心(即使在这里你假设比较字符串可能不是?)。
为什么?
contains
依赖于 equals
并且 equals 与 hashCode
一起工作以判断我们是否在此处谈论引用术语中的同一对象。
根据 equals-hashCode
合同恢复 contains()
工作
More documentation