【问题标题】:Iterate through a Map with duplicate values and identify keys that share these values遍历具有重复值的 Map 并识别共享这些值的键
【发布时间】:2019-07-20 02:16:25
【问题描述】:

我有一个 <String, Set<Object>> 类型的 Map,其中包含名称和坐标 (Double = X,Y)。这些值用于创建图表。我遇到的问题是某些点共享相同的坐标,因此它们几乎看不到,因为它们一个在另一个之上。为了解决这个问题,我想迭代到Set 并仅增加0.01X 点。

虽然这可以显着解决问题,但它并不是一个完美的解决方案,因为某些点仍然会与其他点发生冲突。

有没有办法在Map 中一次搜索特定范围的值,例如0.1-0.2, 0.2-0.3, etc. 并确定keys 出现在这些范围内吗?然后我假设我可以增加在特定范围内共享相同Xs 的那些。这将防止将0.01 添加到key 的所有Xs 中,并且只添加到需要添加的那些。

我的代码:

double i=0.01;

for (Map.Entry<String, Set<Coordinates>> serie : nameToCoordinates.entrySet()) {
    List<Double> xData = new ArrayList<>();
    List<Double> yData = new ArrayList<>();

    for (Coordinates coord : serie.getValue()) {

        xData.add(coord.getX()+i);
        yData.add(coord.getY());

     }

     i=i+0.01;

     chart.addSeries(serie.getKey(), xData, yData);

}

输入示例:

Point1   [[0.1,0.1,0.1,0.1,0.1,0.1],[0.2,0.3,0.4,0.5,0.6,0.7]] 
Point2   [[0.1,0.1,0.1,0.1]        ,[0.4,0.5,0.6,0.7]]                     
Point3   [[0.1,0.1]                ,[0.6,0.7]]

【问题讨论】:

  • 你可以得到valueshttps://docs.oracle.com/javase/8/docs/api/java/util/Map.html#values--然后相互比较,如果需要,你可以通过keySet做同样的事情据我所知,没有共同的访问你问
  • 我不太确定我是否理解问题,例如如果您为每个系列将i 递增0.01(假设Point1 是系列键之一),为什么您的输出总是在x 数组中0.1?您将如何确定这些范围的大小?如果它们是固定的,如果一个系列中的坐标太多怎么办?您的代码也与您的描述不符:您声明地图的值是一个列表,但您的代码使用集合。
  • 我也不确定我是否理解为什么增加坐标会有所帮助。如果标签重叠一个小的增量不会有太大帮助,而更大的增量会扭曲图形,不是吗?也许最好向我们展示您的问题的图片。
  • 顺便说一句,我假设坐标应该包含 X 和 Y 值,那么对数据使用两个不同的数组不是一个好的选择,由于数据完整性,你应该使用一些坐标对象(包括字段为X 和 Y 值)-理论上你不能确定 X 数组中的相同位置将匹配 Y 数组中相同位置的逻辑数据..
  • @Thomas 的输出示例是在我尝试添加 0.01 之前。

标签: java dictionary set


【解决方案1】:

你可以创建一个看起来像这样的函数。它会返回所有在最小和最大范围之间具有 x 或 y 坐标的键。你只需要对它返回的键列表做一些事情。就像增加属于该键的值一样。 当然,稍微更改函数以适应您正在使用的对象类型:p。祝你好运!

private List<String> getKeyRange(Map<String, List<Object> map, double min, double max){
    List<String> keys = new List<>();
    for(String key : map.getKeys()){
        Object coord = map.get(key);
        if( (coords.getX() > min && coords.getX() < max) || (coord.getX() > min && coord.getY() < max) ){
            keys.add(key);
        }
    }
    return keys;
}

【讨论】:

    【解决方案2】:

    注册。这些使用 Map 的操作您需要自己实现它,特别是如果您使用一些自定义对象,请参考下面的例子,您可以如何定义事物:

    坐标对象(包含 X 和 Y 双精度值)

    class CoordObj {
            double Xval;
            double Yval;
    
            public CoordObj(double xval, double yval) {
                Xval = xval;
                Yval = yval;
            }
    
            public double getXval() {
                return Xval;
            }
    
            public double getYval() {
                return Yval;
            }
    
            @Override
            public String toString() {
                return "coord: ["+Xval+"," + Yval +"]";
            }
    
        }
    

    出于测试目的,我创建了生成器函数来填充坐标对象

    HashMap<Integer, CoordObj> dataMap = new HashMap<>();
    
    for (int i = 0; i < itemCount; i++) {
            CoordObj item = new CoordObj(generateDouble(), generateDouble());
            dataMap.put(i, item);
    }
    
    return dataMap;
    

    然后按范围内的 X 坐标进行过滤的工作方式如下(可以很容易地自定义为每个 Y 坐标进行过滤;类似的部分可用于比较两个坐标成员 - 例如带有内循环):

    public static void filterCoordsByX(Map<Integer,CoordObj> data,double min, double max) {
    
            ArrayList<Integer> foundKeys = new ArrayList<>();
            for (Map.Entry<Integer, CoordObj> entryChecked : data.entrySet()){
                    if(entryChecked.getValue().getXval() > min && entryChecked.getValue().getXval() < max ) {
                        foundKeys.add(entryChecked.getKey());
                    }
            }
    
            System.out.println("for min: " + min + ", and max: " + max + " found keys:" + foundKeys.toString());
            System.out.println("backward check:");
            for (int i = 0; i < foundKeys.size(); i++) {
                System.out.println("key: " + foundKeys.get(i) +", value: " + data.get(foundKeys.get(i)));
            }
        }
    

    测试输出

    generated: 3.61911823406948
    generated: 4.970659057619206
    generated: 0.19778377925564672
    generated: 6.223897657222775
    generated: 9.86588783431928
    generated: 4.211157245481315
    generated: 2.4889283969102562
    generated: 9.253484002587617
    generated: 5.003925383598808
    generated: 0.9279033924004261
    for min: 2.0, and max: 4.0 found keys:[0, 3]
    backward check:
    key: 0, value: coord: [3.61911823406948,4.970659057619206]
    key: 3, value: coord: [2.4889283969102562,9.253484002587617]
    

    【讨论】:

    • 如果键的点超出指定范围,这会起作用吗?因为我不希望这些 X 也增加,只希望范围内的 X 增加。
    • 如你所见,这个sn-p只检查“X”坐标,它是generated in range from 0.92 till 9.8,它的filtered from 2.0 until 4.0
    猜你喜欢
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多