简体   繁体   中英

search with multiple parameters, java collection choice advise

What data structure should I use in the case described below:

I have a simple bean:

 public class Points { 

    private String name; 
    private String address; 
    private int phone; 
    private int coord1; 
    private int coord2; 

    //getters+setters 

    }

I would like to create several beans and store them in some sort of data structure. And be able to search with two parameters - name and address.

For example, user types in "7" - and it gives him back several object, which name or address contains this character?

What data structure should i use and how do i search through it?

If it is important, I actually need this to implement into my android app - i would like to search through my points on the map Also I do not want to create a database so far, as there are only 20 of them.

Thank you very much in advance.

A trie seems a good fit. It is an efficient data structure to find all strings with a certain prefix.

If you want to use one of the existing java collections instead, you can use a TreeSet , and its floor() method to get the element before the needed prefix - and then start iterating the set while it still matches.

If you are looking for search by substring , and not only prefix - you might want to use a suffix tree instead.
An (inefficient) alternative that uses java's existing containers - is to store all substrings of your keys in a Set or a Map , but it will require quadric amount of space.

Try java's collection, eg hashmap. Although I ran this on PC, for 10000 items, with search returned 3440 results, it took 76ms.

    class Points {

        String name;
        String address;
        int phone;
        int coord1;
        int coord2;

        // getters+setters
    };

    class PointsIdentifier {

        private String name;
        private String address;

        public PointsIdentifier(String name, String address) {
            this.name = name;
            this.address = address;

        }

        public boolean contains(String seq) {
            return name.contains(seq) || address.contains(seq);
        }

        @Override
        public boolean equals(Object obj) {
            Points other = (Points) obj;
            return name.equals(other.name) && address.equals(other.address);
        }

        @Override
        public int hashCode() {
            return name.hashCode() + address.hashCode();
        }
    };

    class PointsCollection {
        private Map<PointsIdentifier, Points> map;

        public PointsCollection() {
            map = new HashMap<PointsIdentifier, Points>();
        }

        public void add(Points p) {
            map.put(new PointsIdentifier(p.name, p.address), p);
        }

        public List<Points> findIdsContaining(String seq) {
            List<Points> resultList = new ArrayList<Points>();
            for (Entry<PointsIdentifier, Points> entry : map.entrySet()) {
                if (entry.getKey().contains(seq)) {
                    resultList.add(entry.getValue());
                }
            }
            // optionally cache result
            return resultList;
        }
    }

    public class Question_11881630 {

        public static void main(String[] args) {
            PointsCollection places = createCollection(10000);
            System.out.println("Collection created");
        String seq = "1";

        System.out.format("Searching for: \"%s\"\n", seq);
        List<Points> verifySearch = verifySearch(places, seq);
        //show(verifySearch);
    }

    private static void show(List<Points> verifySearch) {
        int i = 1;
        for (Points p : verifySearch) {
            System.out.println(i + ": " + p.name + ", " + p.address);
            i++;
        }
    }

    private static List<Points> verifySearch(PointsCollection places, String seq) {
        long start = System.currentTimeMillis();
        List<Points> searchResult = places.findIdsContaining(seq);
        System.out.println("Search results: " + searchResult.size());
        long end = System.currentTimeMillis();
        System.out.println("Operation time: " + formatTime(end - start));
        return searchResult;
    }

    private static String formatTime(long elapsed) {
        return elapsed + " miliseconds";
    }

    private static PointsCollection createCollection(int number) {
        PointsCollection coll = new PointsCollection();
        while (number > 0) {
            coll.add(createSamplePoint(number));
            number--;
        }
        return coll;
    }

    private static Points createSamplePoint(int number) {
        Points p = new Points();
        p.name = "VeryVeryLongName: " + number;
        p.address = "VeryVeryLongLongAddress: " + number;
            p.coord1 = 123;
            p.coord2 = 456;
            return p;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM