【问题标题】:Java HashSet<> : Return false if HashSet contains values other than specifiedJava HashSet<> :如果 HashSet 包含指定以外的值,则返回 false
【发布时间】:2018-05-05 17:19:52
【问题描述】:

所以我提取了一个字符串列表,例如 {"ADD","DEL","CHG","DEL","NA","ADD","BLAH","YAK",....} 从JSON 请求并将它们传递到哈希集以避免重复。 如果 HashSet 除了“ADD”或“NA”或两者都有,我如何让我的函数返回 false? 任何帮助表示赞赏。

更新: 在我的代码中,我只是在所有我可能想到的不需要的值周围添加了一个 NOT 条件。我需要一个更有效的解决方案。

另外:我的 true() 条件是 ADD 必须始终存在,而 NA 是可选的。除了强制的 "ADD" 和可选的 "NA" 之外,不得存在其他值。 例如:

  1. {ADD} 返回真
  2. {ADD,NA} 返回真
  3. {ADD,DEL} 返回错误
  4. {DEL,YAK} 返回 false 等。

下面的 sn-p 没有这个检查,我正在寻找最少冗长的最佳解决方案。

这里是sn-p。字符串列表作为参数传递给 isAddOrNa()。

private boolean isAddOrNa(List<AllActions> allActions) {
    Set<String> actions = new HashSet<>();
    for (com.demo.Action action : allActions) {
        actions.add(action.getName());
    }
    return ((actions.size() <= 2) && (actions.contains("ADD") || actions.contains("NA"))) &&
            !(actions.contains("DEL") || actions.contains("CHG") || actions.contains("BLAH") || actions.contains("YAK"));
}

【问题讨论】:

  • 到目前为止你尝试了什么?发布您的代码!运行时发生了什么?你期望会发生什么?你具体有什么问题? stackoverflow.com/help/mcve
  • 两者或“两者”?
  • "both" 在这两个值中。
  • 如果你的目标是迷惑,那你肯定成功了......
  • 对不起,太晚了,但我现在已经删除了“两者”中的引号。

标签: java hashset


【解决方案1】:
 import com.google.common.collect.Sets;
 String add= "ADD";
 String NA ="NA"
 final Set<String> Strings = Sets.newHashSet("ADD","DEL","CHG","DEL","NA","ADD","BLAH","YAK");

 if (!((Strings .contains(add))||(Strings .contains(NA )))){
 return false;
 }

根据你的要求,

if(String.contains(add)){
    if(String.contains(NA)){
        return true;
          }
     }
 return false;

【讨论】:

  • 对不起,我之前没有给你这个更新。我的 true() 条件是 ADD 必须始终存在,而 NA 是可选的。除了强制性的“ADD”和可选的“NA”之外,不得存在其他值。如果只有“NA”不存在,上述条件将返回 true。
  • 如果 NA 是可选的,那么你只能有条件“添加”。 if(!String.contains(add)){ return false;}
  • 我的意思是 {ADD,NA} 可以为真,{ADD} 可以为真,但 {ADD,DEL} 或 {ADD,YAK} 或 {DEL,YAK} 将是假的。
  • 不仅 ADD 必须始终存在,而且任何其他值以及 ADD(NA 除外)都应该返回 false。
【解决方案2】:

您的 List 有多大或您的意图是什么超出了我的范围,但根据您提供的内容,我想到的一个天真的解决方案是在 HashSet 上对那些选定的单词进行 3 次搜索,并保留一个计数器跟踪点击量。然后将其与 HashSet 的 size() 进行比较。

【讨论】:

  • 请阅读How to Answer。不要仅仅因为您还没有必要的代表而发布 cmets 作为答案。不要滥用系统。
  • 请不同意,@JimGarrison。这确实回答了所问的问题。此外,它不会免费提供代码,坦率地说,OP 不值得付出这么少的努力。我们可以讨论这是否是问题的最佳解决方案,但答案的格式是我喜欢的。
【解决方案3】:

if(hashSet.contains("ADD")||(hashset.contains("NA")) 返回错误;

感谢使用它

【讨论】:

  • 我的 true() 条件是 ADD 必须始终存在,而 NA 是可选的。除了强制性的“ADD”和可选的“NA”之外,不得存在其他值。如果仅存在“NA”,则上述条件将返回 true,这不是预期的。
【解决方案4】:

您的问题的解决方案是检查输入集中除“NA”和“ADD”之外的任何内容。这可以通过将输入集与验证集添加来实现,同时如果在输入集中没有找到新元素,您将得到 false,否则为 true:

            import java.util.HashSet;
            import java.util.Set;

            public class HashSetTheory {

                public static void main(String args[]){

                    String[] sourceData = {"ADD","DEL","CHG","DEL","NA","ADD","BLAH","YAK" }; // Output is false
                    //String[] sourceData = {"ADD","ADD","ADD","NA","NA","ADD","NA","ADD" };  // Output is true
                    //String[] sourceData = {"ADD","ADD","ADD" };  // Output is true
                    //String[] sourceData = { };  // Output is false
                    //String[] sourceData = { "NA" , "Something"};  // Output is false

                    Set<String> myRepo = new HashSet<>();

                    // Populating the set with input data
                    for(String data : sourceData){
                        myRepo.add(data);
                    }

                    Set<String> check = new HashSet<>();
                    check.add("NA");
                    check.add("ADD");

                    System.out.println("==>" + validateData(myRepo,check) );

                }

                public static boolean validateData(Set<String> myRepo,Set<String> check){
                    boolean retVal = true;

                    if(myRepo.size()==0){
                        return false;
                    }

                    for (String s : myRepo) {
                        // Adding an element in set returns false if it already exists
                        if(check.add(s)){
                            //This check is pass only if the set has some new item in it
                            retVal = false;
                            break;
                        }
                    }

                    return retVal;
                } 

            }

【讨论】:

    【解决方案5】:

    据我了解,您希望为您的Set 提供一种验证方法。例如,如果来自 JSON 的列表只是 {“ADD”、“NA”、“ADD”},那很好,您的方法应该返回 true。如果列表中还有其他值,例如问题中的示例,它应该返回 false。

    当你知道怎么做时,这并不复杂:

    private static boolean setHasOnlySpecifiedValues(
            Set<String> specifiedValues, Set<String> setToCheck) {
        // we check setToCheck by removing specifiedValues and seeing if there are any
        // values left: however, the caller may be surprised if we remove elements from
        // the set passed to us, so work on a copy instead
        Set<String> workingCopy = new HashSet<>(setToCheck);
        workingCopy.removeAll(specifiedValues);
        if (workingCopy.isEmpty()) { // there were only specified values
            return true;
        } else {
            System.out.println("The set contained other values: " + workingCopy);
            return false;
        }
    }
    

    Java 集合框架中的removeAll 方法是所谓的集合操作之一(不是因为它适用于集合,它也适用于列表和映射)。您可以将其视为集差操作的实现。

    让我们试试这个方法:

        List<String> fromJson 
                = Arrays.asList("ADD", "DEL", "CHG", "DEL", "NA", "ADD", "BLAH", "YAK");
        Set<String> setToCheck = new HashSet<>(fromJson);
        Set<String> specifiedValues = new HashSet<>(Arrays.asList("ADD", "NA"));
        // or in Java 9: Set<String> specifiedValues = Set.of("ADD", "NA");
    
        boolean ok = setHasOnlySpecifiedValues(specifiedValues, setToCheck);
        System.out.println("The result of the check is: " + ok);
    

    打印出来:

    The set contained other values: [YAK, CHG, DEL, BLAH]
    The result of the check is: false
    

    最后,您可能不希望在检查方法中使用System.out.println() 语句。我现在把它放在那里,这样你就可以看到removeAll() 的确切结果。

    【讨论】:

    • 我的 true() 条件是 ADD 必须始终存在,而 NA 是可选的。除了强制性的 "ADD" 和可选的 "NA" 之外,不得存在其他值。您能否更新一下我们如何在您的解决方案中添加此检查?
    • 添加条件setToCheck.contains("ADD")即可。 @sahilsahadevan
    【解决方案6】:
    private boolean isAddOrNa(List<AllActions> allActions) {
        Set<String> actions = new HashSet<>();
        for (com.demo.Action action : allActions) {
            actions.add(action.getName());
        }
        return actions.contains("ADD") && ((actions.contains("NA") && actions.size() ==2) || (!actions.contains("NA") && actions.size() ==1));
    }
    

    最小化条件。这有帮助吗?

    【讨论】:

    • 不幸的是,如果 allActions 仅包含“ADD”,则此条件将返回 false。此外,||(!actions.contains("NA") && actions.size() ==1)) 如果 allActions 包含其他值(如 DEL)将返回 true。这个逻辑有很多问题。
    • 我测试过了。有用。我的解决方案检查它是否包含“ADD”,如果 hashset 包含“NA”,那么它的大小必须为 2,否则大小将为 1。
    • 抱歉,在将其粘贴到我的 IDE 中进行测试后,我误解并放错了括号。这行得通,谢谢。
    猜你喜欢
    • 2015-09-18
    • 2015-01-30
    • 2023-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2021-09-23
    相关资源
    最近更新 更多