Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
648 views
in Technique[技术] by (71.8m points)

java - Implementing a Map where keys are sets of non-overlapping ranges

I am facing a performance issue with my current implementation using List and loops. I was thinking to make some custom Map but is it possible to override the getter properly to work with following setup:

Map contains custom objects and key can be following:

case A key: "10"
calling get("10") would return matching object

case B key: "10;12;14"
calling get("10"),get("12"),get("14") would return same object

case C key: "10;20-30"
calling get("10"), get(value between 20 and 30) would return same object

Is using a Map in this kind of scenario the best way, what could be the alternatives?

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

UPDATE: Added full implementation

UPDATE 2: If you want you can use RangeMap for internal theMap as suggested in the comments.

If you key ranges don't overlap, you can create a custom container which internally stores data in TreeMap with a custom key which implements Comparable:

class MyStorage<T> {
    private static final class Range implements Comparable<Range> {
        private int first;
        private int last;

        public Range(int first_, int last_) {
            first = first_;
            last = last_;
        }

        // This heavily relies on that the ranges don't overlap
        @Override public int compareTo(Range other) {
            if (last < other.first)
                return -1;
            if (first > other.last)
                return 1;
            return 0;
        }
    }

    private Map<Range, T> theMap = new TreeMap<Range, T>();

    public void put(String key, T obj) {
        String[] ranges = key.split(";");
        for (String range : ranges) {
            //System.out.println("Adding " + range);
            String[] bounds = range.split("-");
            //System.out.println("Bounds " + bounds.length);
            int first = Integer.parseInt(bounds[0]);
            if (bounds.length == 1)
                theMap.put(new Range(first, first), obj);
            else 
                theMap.put(new Range(first, Integer.parseInt(bounds[1])), obj);
        }
    }

    public T get(String key) {
        return get(Integer.parseInt(key));
    }

    public T get(int key) {
        return theMap.get(new Range(key, key));
    }
}

class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
        MyStorage<Integer> storage = new MyStorage<Integer>();
        storage.put("10;20-30", 123);
        storage.put("15;31-50", 456);

        System.out.println(storage.get("42"));
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...