【问题标题】:java: check if an object's attribute exists in HashMap valuesjava:检查对象的属性是否存在于HashMap值中
【发布时间】:2017-04-08 22:48:24
【问题描述】:

我有一个带有Double 类型的key 和我的自定义对象作为value 的HashMap。 它看起来像这样:

private static Map<Double, Incident> incidentHash = new HashMap<>();

Incident 对象具有以下属性:String dateString addressString incidentType

现在我有一个String date 作为输入从用户那里得到,我想检查 HashMap 中是否存在 any 事件以及用户输入的日期。在给定日期的 HashMap 中可以有很多事件,但只要给定日期至少有一个事件,我就可以* 某事

我可以遍历 HashMap 中的所有值并检查给定日期是否存在,但我想知道是否有任何更好、更有效的方法,而无需修改数据结构。

【问题讨论】:

  • 你当前的密钥是什么?

标签: java data-structures hashmap


【解决方案1】:

鉴于您的 HashMap,,没有其他方法可以做到这一点不迭代该 HashMap

至于改变结构,你可以像Map&lt;String, List&lt;Incident&gt;&gt;那样做,这样你就有一个date作为键和一个List该日期的事件,给定你的要求:There can be many Incidents in the HashMap with the given date

所以这将是O(1)

 //considering that the key is added when you have at least one incident
 if (yourHash.get("yourDateStringWhatEverTheFormatIs") != null)

【讨论】:

    【解决方案2】:

    您可以使用如下代码所示的流 API(来自 Java8)和内联 cmets:

    String userInput="10-APR-2017";
    
    Optional<Map.Entry<Double, Incident>> matchedEntry = 
      incidentHash.entrySet().stream().
      //filter with the condition to match
      filter(element -> element.getValue().getDate().equals(userInput)).findAny();
    
     //if the entry is found, do your logic
     matchedEntry.ifPresent(value -> {
                //do something here
     });
    

    如果你正在寻找JDK1.8之前的东西,你可以参考下面的代码:

    String userInput="10-APR-2017";
    Set<Map.Entry<Double, Incident>> entries = incidentHash.entrySet();
    Map.Entry<Double, Incident> matchedEntry = null;
    for(Iterator<Map.Entry<Double, Incident>> iterator = entries.iterator(); 
                        iterator.hasNext();) {
        Map.Entry<Double, Incident> temp = iterator.next();
        if(temp.getValue().getDate().equals(userInput)) {
            matchedEntry = temp;
            break;
        }
    }
    

    【讨论】:

    • 我要补充一点,这只是 Java 8 ;)
    • 他的问题除了迭代之外还有其他方法。这真的还在搜索集合。
    【解决方案3】:

    您可以将TreeMap 与您的自定义Comparator 一起使用。在您的 Comparator 中比较日期的值。

    【讨论】:

      【解决方案4】:

      您必须遍历地图,直到找到匹配的数据。由于您只需要知道是否存在任何匹配项,因此您可以在找到匹配项时简单地退出循环,而不是迭代地图的其余部分。

      【讨论】:

        【解决方案5】:

        您只能保留第二个与该属性匹配的 Hash/TreeMap 对象,因此您也可以快速检查此属性。但是您必须为您想要快速访问的每个属性策划一个这样的地图。这使得它更复杂一些并使用更多内存,但速度会快得多。

        如果这不是一个选项,则其他答案中引用的流 API 是一种很好且整洁的方式来迭代所有对象以搜索属性。

        private static Map<Double, Incident> incidentHash = new HashMap<>();
        private static Map<String, List<Incident>> incidentsPerDayMap = new HashMap<>();
        

        【讨论】:

          【解决方案6】:

          鉴于您不想 iterate 映射并且目前这是获取所需值的唯一方法,我建议推荐另一个包含 Date 作为键的 MapList&lt;Incident&gt; 作为值。可以是TreeMap,例如:

          Map<Date, List<Incident>> incidents = new TreeMap<>();
          

          只要将条目添加到原始Map 中,您就可以在此Mapput 条目,例如:

          Incident incident = ;// incident object
          Date date; //Date
          incidents.computeIfAbsent(date, t -> new ArrayList<>()).add(incident);
          

          一旦用户输入Date,您就可以通过incidents.get()获取属于该日期的所有事件。虽然这会给你一个list 并且你仍然需要对其进行迭代,但它将包含更少的元素,TreeMap 中的get 方法将保证你log n 排序的复杂性。因此,您的搜索操作会更有效率。

          【讨论】:

            猜你喜欢
            • 2020-11-30
            • 1970-01-01
            • 2021-12-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多