简体   繁体   English

contains()方法不起作用

[英]contains() method not working

private List<String> values = new ArrayList<String>();

public WhitespaceEqualsTest() {
    values.add("I ");
    values.add("I");
    values.add(". ");
    values.add(".");
    values.add("1");
    values.add("1 ");

    System.out.println(refine(values));
}

private List<String> refine(List<String> input){
    ArrayList<String> outerLoopValues = (ArrayList<String>) input;
    ArrayList<String> innerLoopValues = (ArrayList<String>) input;
    ArrayList<String> results = new ArrayList<String>();

    for(String string1 : outerLoopValues){
        for(String string2 : innerLoopValues){
            if(string1.contains(string2) == false){
                results.add(string1);
            }
        }
    }

    Set<String> temp = new HashSet<String>();
    temp.addAll(results);
    results.clear();
    results.addAll(temp);

    return results;
}
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((values == null) ? 0 : values.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;
    WhitespaceEqualsTest other = (WhitespaceEqualsTest) obj;
    if (values == null) {
        if (other.values != null)
            return false;
    } else if (!values.equals(other.values))
        return false;
    return true;
}

I've overriden the hashCode() and equals() , so I'm not really sure what's wrong. 我已经覆盖了hashCode()equals() ,所以我不太确定这是怎么回事。 They are generated using Eclipse (Source -> Generate hashCode() and equals()). 它们是使用Eclipse生成的(源->生成hashCode()和equals())。 Why isn't it detecting that the same character without a space is contained within a character with a space? 为什么没有检测到带有空格的字符中包含相同的没有空格的字符? The output is: 输出为:

[1, . , I , I, ., 1 ]

As mentioned in one of the comments, you should be using a String wrapper to wrap the strings and override the equals and hashcode methods. 如注释之一所述,您应该使用字符串包装器包装字符串并覆盖equals和hashcode方法。

My solution is based on the assumption that "I " should be equals to "I" , hence only one of them should be added into the result. 我的解决方案基于这样的假设: "I "应等于"I" ,因此仅应将其中一个添加到结果中。

However I'll need to addon that based on the documentation in Java Objects and Java Arraylist with regards to equals and contains implementation respectively. 但是,我需要根据Java ObjectsJava Arraylist中的文档分别添加关于equalscontains实现的内容。 The hashcode method would have to return a common value. hashcode方法将必须返回一个公共值。 I've written the explanation in the code as comments. 我已经在代码中写了解释作为注释。 Let me know if there are any issues. 让我知道是否有任何问题。

Main Class 主班

public class StackOverflowMain
{
    private static List<String> values = new ArrayList<String>();

    public static void main(String[] args) {

        values.add("I ");
        values.add("I");
        values.add(". ");
        values.add(".");
        values.add("1");
        values.add("1 ");
        List<WhitespaceEqualsTest> toRefineList = new ArrayList<WhitespaceEqualsTest>();
        for (String value : values) {
            toRefineList.add(new WhitespaceEqualsTest(value));
        }

        System.out.println(refine(toRefineList));
    }

    private static List<WhitespaceEqualsTest> refine(List<WhitespaceEqualsTest> input) {
        ArrayList<WhitespaceEqualsTest> loopValues = (ArrayList<WhitespaceEqualsTest>) input;
        ArrayList<WhitespaceEqualsTest> results = new ArrayList<WhitespaceEqualsTest>();

        for (WhitespaceEqualsTest value : loopValues) {
            if (!results.contains(loopValues)) {
                results.add(value);
            }
        }

        Set<WhitespaceEqualsTest> temp = new HashSet<WhitespaceEqualsTest>();
        temp.addAll(results);
        results.clear();
        results.addAll(temp);

        return results;

    }
}

Inner WhitespaceEqualsTest Class 内部WhitespaceEqualsTest

class WhitespaceEqualsTest {
    private String value;

    public WhitespaceEqualsTest(String value) {
        this.value = value;
    }

    public void setString(String value) {
        this.value = value;
    }

    public String getString() {
        return this.value;
    }

    public int hashCode() {
        /*
         * Arraylist.contains is evaluated by using (o==null ? e==null : o.equals(e)) as mentioned in the javadoc
         * and Object.equals() would evaluate using hashcode() first to check if the object o is equal to object e
         * before calling .equals() method to evaluate.
         * 
         * As mentioned in java doc at http://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#equals(java.lang.Object)
         * c1.equals(c2) implies that c1.hashCode()==c2.hashCode() should be satisfied
         * which is not in this question
         */      
        return 0;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        WhitespaceEqualsTest other = (WhitespaceEqualsTest) obj;
        if (value == null) {
            if (other.value != null)
                return false;
        } else if (!value.contains(other.value) && !other.value.contains(value)){ 
            /*
             * Does a checking on both ends since "I " contains "I" but "I" does not contain "I " due to the whitespace
             * For this question, if one of the condition satisfy it should be equal
             */
            return false;
        }           
        return true;
    }

    @Override
    public String toString() {
        return this.value;
    }
}

Result 结果

[I , . , 1]

String class is final. 字符串类是最终的。 So you cannot override its equals and hashCode methods. 因此,您不能覆盖其equals和hashCode方法。

private List<StringWrapper> values = new ArrayList<StringWrapper>();

public WhitespaceEqualsTest() {
    values.add(new StringWrapper("I "));
    values.add(new StringWrapper("I"));
    values.add(new StringWrapper(". "));
    values.add(new StringWrapper("."));
    values.add(new StringWrapper("1"));
    values.add(new StringWrapper("1 "));

    System.out.println(refine(values));
}

private List<StringWrapper> refine(List<StringWrapper> input){
    //no need to iterate the list
    //the set will automatically cancel out the duplicate
    Set<StringWrapper> temp = new HashSet<StringWrapper>(input);

    ArrayList<StringWrapper> results = new ArrayList<StringWrapper>();
    results.addAll(temp);
    return results;
}

Create a wrapper class of String then override the equals and hashcode method. 创建String的包装器类,然后覆盖equals和hashcode方法。

class StringWrapper {
    private String value;

    public StringWrapper(String value){
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
    @Override
    public String toString(){
        return value;
    }
    @Override
    public boolean equals(Object obj){
        boolean result = Boolean.FALSE;
        if(obj != null && obj instanceof StringWrapper){
            StringWrapper stringWrapper = (StringWrapper) obj;
            result = value.trim().equals(stringWrapper.getValue().trim());
        }
        return result;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((value.trim() == null) ? 0 : value.trim().hashCode());
        return result;
    }
}

You add the values to a Set. 您将值添加到集合。 In a Set in any case a value occurs once - hence it is a set. 在任何情况下,一个集合中的值只出现一次-因此它是一个集合。 ;) ;)

You might as well modify the loop to see what happens 您最好修改循环以查看会发生什么

for(String string1 : outerLoopValues){
            for(String string2 : innerLoopValues){
                if(string1.contains(string2) == false){
                    results.add(string1);
                    System.out.println("added \"" + string1 + "\" since it does not contain \"" + string2 + "\"");
                }
            }
        }

Giving the following output: 提供以下输出:

added "I " since it does  not contain ". "
added "I " since it does  not contain "."
added "I " since it does  not contain "1"
added "I " since it does  not contain "1 "
added "I" since it does  not contain "I "
added "I" since it does  not contain ". "
added "I" since it does  not contain "."
added "I" since it does  not contain "1"
added "I" since it does  not contain "1 "
......
[1, . , I , I, ., 1 ]

To add them if they do not contain each other is the idea i guess? 如果它们彼此不包含,添加它们是我的想法吗?

Then pushing the List through a Set removes the duplicates! 然后通过集合推送列表将删除重复项! See here: Does adding a duplicate value to a HashSet/HashMap replace the previous value 参见此处: 向HashSet / HashMap中添加重复值是否替换了先前的值

Changing the condition in the Loop from false to true yields this (no change after using the Set/HashSet in the last line of output!) 将Loop中的条件从false更改为true会产生此结果(在输出的最后一行中使用Set / HashSet之后,将保持不变!)

added "I " since it does contain "I "
added "I " since it does contain "I"
added "I" since it does contain "I"
added ". " since it does contain ". "
added ". " since it does contain "."
added "." since it does contain "."
added "1" since it does contain "1"
added "1 " since it does contain "1"
added "1 " since it does contain "1 "
[1, . , I , I, ., 1 ]

Which answers your question: It does detect if eg "I " contains "I". 回答您的问题:它确实检测例如“ I”是否包含“ I”。

System.out.println("I ".contains("I"));

says "true" 说“真”

Hope this helps ^^-d 希望这可以帮助^^-d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM