【问题标题】:Return Key Based on Range of Values in a TreeSet within Map根据 Map 中 TreeSet 中的值范围返回键
【发布时间】:2013-04-16 15:47:11
【问题描述】:

第一次在这里发帖,我对 Java(和一般编程)非常陌生!

我正在尝试了解如何在地图包含其他集合时对其进行操作。我正在尝试编写代码来将名称存储为针对 Map 中的整数集的值的键。然后,我希望能够返回具有给定范围内的元素的任何值的键。

Map<String, Set<Integer>> index = new TreeMap<>();
Set<Integer> numbers = new TreeSet<>;

numbers.add(80);
numbers.add(90);
numbers.add(100);
index.put("Adam", numbers);

numbers = new TreeSet<>();
numbers.add(30);
numbers.add(40);
numbers.add(50);
index.put("Eve", numbers);

我现在有一个带有键“Adam”和值 [80,90,100] 的条目和另一个带有键“Eve”和值 [30,40,50] 的条目的 Map。至少我认为我有!

我现在希望能够返回任何包含在给定范围内的值的键的名称。

例如,如果范围是 25 到 50,则返回值为“Eve”。 如果范围是 50 到 85,则返回值将是“Adam”和“Eve”。

我认为 containsValue() 可能有效但无效(因为 Set?)。

任何指导将不胜感激。

【问题讨论】:

  • 对您的问题域一无所知:您是否考虑过相反的情况 - 使用数字作为键,使用一组名称作为 TreeMap 中的值?根据您的描述,这似乎适合您的使用方式。
  • 谢谢,您的问题刚刚突出了另一个问题。可能有重复的值,所以我不能按照你的建议做,但我也不能使用 TreeSet。我认为我需要一个 ArrayList?
  • 如果你想避免重复,你会使用 Set 而不是 List;并且只有在需要对其进行排序(通过可比较的东西)时才使用基于树的集合实现(TreeMap、TreeSet)。一般来说,首先确定是否需要 List、Set 或 Map,然后查看常见的 ArrayList、HashMap 或 HashSet 是否足够。仅当他们不这样做时,才考虑使用基于树或基于 LinkedList 的集合实现。
  • 我明白了。我想允许重复,所以我需要一个 ArrayList,但我也想要排序的值,所以我可以使用 Collections.sort(numbers) 吗?我将不得不查找 HashMap 和 HashSet。对不起,我确实说过我是新手!! :-)

标签: java map integer set


【解决方案1】:

在不改变您的设计的情况下,我能想到的唯一方法是遍历地图和每个值集,但效率不高:

public Set<String> containsRange(Map<String, Set<Integer>> index, int lowerBound, int upperBound){
    Set<String> result = new HashSet<>();
    for (Map.Entry<String, Set<Integer>> entry : index.entrySet()) {
        String string = entry.getKey();
        for (Integer integer : entry.getValue()) {
            if (integer >= lowerBound && integer <= upperBound) {
                result.add(string);
                break;
            }
        }
    }
    return result;
}

未测试。

【讨论】:

    【解决方案2】:

    第一眼就能想到这个算法

    1)制作一个Hashset来存储关键结果

    2) 迭代 thu 映射,然后迭代每个集合的元素。

    3) 将其与输入范围进行比较。

    4) 如果它位于那里,则将其添加到哈希集中。

    5) 就是这样

    这里使用哈希集,因为它将确保唯一的密钥结果。

    【讨论】:

    • 嗨,这听起来像是我一直在尝试做的(没有成功)。我遍历了地图,然后遍历了集合的每个元素,将每个元素与输入范围进行了比较,只给了我需要的值。您能否再解释一下我如何使用这些值将关联的键放入 Hashset 中?
    【解决方案3】:

    您必须编写一个自定义逻辑来遍历映射中每个条目的每个集合,如果它在所需的范围内,则获取该条目的相应键。

    【讨论】:

    • 嗨,我已经尝试遍历地图中每个条目的每个集合,并且可以隔离该范围内的值。我只是在获取相应的密钥时迷路了?
    【解决方案4】:

    我认为您无法使用任何标准地图方法来完成此操作。特别是,地图非常适合通过键访问事物,但不能通过值访问。

    我认为在这种情况下,您最好创建一个自定义对象的列表。自定义对象将包含值列表和字符串。当您想要获取具有该范围内的值的所有字符串时,您将遍历列表并用匹配的字符串填充一个新列表。

    这就是它的样子:

    List<RangedString> index = new ArrayList<RangedString>();
    ...
    public List<String> getStringInRange(int low, int high) {
        List<String> results = new ArrayList<String>();
        for (RangedString rangedString : index) {
            if (rangedString.inRange(low, high)) {
                results.add(rangedString.getString());
            }
        }
    }
    

    RangedString.inRange 方法如下所示:

    Set<Integer> values;
    ...
    public boolean inRange(int low, int high) {
        for (Integer value : values) {
            if (value >= low && value <= high) {
                return true;
            }
        }
        return false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 2022-10-01
      相关资源
      最近更新 更多