【问题标题】:Is there a better way to look up something from a List?有没有更好的方法从列表中查找内容?
【发布时间】:2021-07-16 22:06:33
【问题描述】:

我有以下帮助函数,它可以查看两个列表并基于一个字段。确定要返回列表中的哪些对象。正在寻找的对象是列表 A 中的 5 种类型之一,或列表 b 中的 2 种类型之一……但是,如果存在不止一种类型(很可能),则类型需要优先于其他...因此,如果列表 A 和 B 中都存在 TYPE_4,则需要优先考虑列表 A 中的那个。此外,如果列表 A 中同时存在 TYPE_1 和 TYPE_2,则它们的首选项是给 TYPE_1。 IF 列表 B 包含 TYPE_1、TYPE_2。或 TYPE_3,根本不考虑它们...只应考虑列表 B 中的 TYPE_4 和 TYPE_5。

private static SomeObject getFavoredObject(
            List<SomeObject> listA,
            List<SomeObject> listb)
    {
        Map<String, SomeObject> typeMap = new HashMap<>();

        listA.forEach(a -> typeMap.put("A " + a.getType(), a));
        listB.forEach(a -> typeMap.put("B " + a.getType(), a));

        if (typeMap.containsKey("A TYPE_1")) {
            return typeMap.get("A Type_1");
        }
        if (typeMap.containsKey("A TYPE_2")) {
            return typeMap.get("A TYPE_2");
        }
        if (typeMap.containsKey("A TYPE_3")) {
            return typeMap.get("A TYPE_3");
        }
        if (typeMap.containsKey("A TYPE_4")) {
            return typeMap.get("A TYPE_4");
        }
        if (typeMap.containsKey("A TYPE_5")) {
            return typeMap.get("A TYPE_5");
        }
        if (typeMap.containsKey("B TYPE_4")) {
            return typeMap.get("B TYPE_4");
        }
        if (typeMap.containsKey("B TYPE_5")) {
            return typeMap.get("B TYPE_5");
        }

        return new Address();
    }

困扰我的是 if 语句的序列......当然有更优雅的方式来处理这个问题。我几乎有一个使用地图的解决方案,在我将列表 A 和列表 B 添加到 typeMap 之前,我对它们进行了排序,但是第二次我这样做了,typeMap 没有排序......所以我最终拉错了一个(嘘)。一个多小时以来,我一直在努力解决这个问题,现在是星期五,一天结束了。我要去喝啤酒了。如果有人能想出一些更优雅的东西,不涉及大量代码,减少“重复代码”(我们使用声纳,早期报告显示这个代码段有问题)或者可以指出我朝着正确的方向前进,我将不胜感激。

【问题讨论】:

  • 如果列表a没有TYPE_1TYPE_2,而列表b有呢?
  • 有一个顺序的偏好。所以解决方案是对其进行相应的排序,然后得到首选的(标准排序是升序,所以要么得到最后一个,要么降序排序并得到第一个)。常规的 Map 没有排序(你需要一个 SortedMap),所以这就是(至少一个原因)你的尝试失败的原因。
  • @Kayaman - 哦,FFS……它一直盯着我的脸。有时你就是只见树木不见森林。这就是我在经过一整天的会议后在周五晚些时候开发的结果。
  • @devReddit - 在这种情况下 - 这也很有可能 - 它们被忽略了。列表 B 中应该考虑的唯一类型是 TYPE_4TYPE_5

标签: java list hashmap


【解决方案1】:

代码的中心部分可以写成一个数组循环。

// This array should probably be static and final
// outside this method, assuming a fixed set of keys
String[] keys = {
     "A TYPE_1",  "A TYPE_2", ...
     "B TYPE_4",  "B TYPE_5
 };

 for (String key : keys) 
    if (typeMap.containsKey(key) 
        return typeMap.get(key);

另外,假设 SomeObject 永远不会为空,我会避免双重映射访问:

 for (String key : keys) {
     SomeObject obj = typeMap.get(key);
     if (obj != null) return obj;
 }

【讨论】:

    【解决方案2】:

    您可以定义一个偏好列表并在此基础上处理整个事情:

    public static final String[] preferences = {"A TYPE_1", "A TYPE_2", "A TYPE_3",
            "A TYPE_4", "A TYPE_5", "B TYPE_4", "B TYPE_5"};
    

    您可以使用 for 循环遍历这些首选项并检查您是否可以获得可用的对象以返回。

    private static SomeObject getFavoredObject(
            List<SomeObject> listA,
            List<SomeObject> listB) {
        Map<String, SomeObject> typeMap = new HashMap<>();
    
        listA.forEach(a -> typeMap.put("A " + a.getType(), a));
        listB.forEach(a -> typeMap.put("B " + a.getType(), a));
    
        SomeObject res = null;
        for (String preference: preferences) {
            res = typeMap.get(preference);
            if (res != null) {
                return res;
            }
        }
    
        return new SomeObject("");
    }
    

    【讨论】:

      猜你喜欢
      • 2011-04-09
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多