0

I have code where I need to store a range of y-y and z-z co-ordinates as one single key to a HashMap.

Currently, I'm iterating through every y and z co-ordinate; wrapping them in a Tuple and then saving that Tuple as a key to a designated value. This, however, doesn't seem efficient to me as memory usage can become a problem.

Let's say I have a y range of between 50-100 and the z range also 50-100. Is it possible to store the y and z ranges and as a valid example (75,75) retrieve the value mapped to ranges? 101,101 would be an invalid example.

Finally, I also need to prevent the key pair overlapping with either x or z.

If anyone could help me with this it would be much appreciated as I am puzzled.

Regards

  • can you give example of some key/value pairs ? Not sure to understand – azro Jul 27 '17 at 07:16
  • Please give us a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). I don't get what you're trying to do from the description – Robin Topper Jul 27 '17 at 07:18
  • @azro The key would be `new Tuple(new Range(25, 75), new Range(25, 75))` for example and a value will be any object. I want to be able to retrieve value from the key of that of two given ints that are in range of both the values in Tuple class without having to use direct iteration – John Harmon Jul 27 '17 at 07:20
  • You lay use iteration, because for Map you need equality to get back a value from the key, in fact give the same Tuple with same Range, but this is clearly not what you wan't to do, you want to give 2 ints in both Range, you may proper iteration (or Stream), – azro Jul 27 '17 at 07:48
  • The problem with iteration is performance for me. – John Harmon Jul 27 '17 at 08:02
  • You asked a question, some answers, by respect you may think about accept or vote up answer for those who spent time for you – azro Jun 21 '18 at 12:39

2 Answers2

0

You are probably looking for an IntervalTree.

I posted an example here a while ago.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
0

I made some suppositions from your implementation :

public class Range {    
    private final int from;    
    private final int to;
}
// - - AND - - 
public class Tuple {    
    private final Range rf;    
    private final Range rt;
}

I propose to add the following methods :

// In Range class
public boolean isValid(int x) {
     return (from <= x) && (x <= to);
}
//-----------------------------------------------------------------
// In Tuple class
public boolean isValid(int x, int y) {
     return rf.isValid(x) && rf.isValid(y);
}

And a class to manage your stuff :

public class TupleGestion {   
    private static final Map<Tuple, String> map = new HashMap<>();

    private static String getValue(int x, int y) {

        return map.get(map.keySet().stream()
                          .filter(key -> key.isValid(x, y)).findAny().orElse(null));
    }

    public static void main(String[] args) {
        map.put(new Tuple(new Range(25, 75), new Range(25, 75)), "foo");

        System.out.println(getValue(0, 0));    // null
        System.out.println(getValue(50, 0));   // null
        System.out.println(getValue(0, 50));   // null
        System.out.println(getValue(50, 50));  // foo
    }

}

This will read over the key and find one which correspond to your attemp, have the 2 ints into both range


EDIT - Performance :

  • add 6000 random elements in the map : <5ms
  • use nanoTime() to compute the time it takes for use getValue() :
    • only getValue() for 20000 times : 100ms< t < 150ms
    • System.out.println(getValue()) 20000 times : 850ms< t <1sec

You were asking about 3000 elements and 1000 getValue() : <5ms (200 times lower than 1sec)

azro
  • 53,056
  • 7
  • 34
  • 70