shiv
shiv

Reputation: 497

how to implement Custom Auto suggestion in java like google

how to implement Java Based Auto suggestion. suppose I have different types of data like firstName, rollNumber, address.

My first requirement is like if user enter first character on text box, then result should be sorted on natural order based on firstName and 10 results should be display.

after space if use enter second character and if it is numbere then RollNumber else lastName should be sorted on natural order as ascending.

or if user type third character then Address should be display on ascending order. there should be no database, you don't have to implement Solr or other api. how to implement on pure Java.

here I did not implement the text-box,but I Just took an example to demonstrate

    import java.util.*;
    import java.lang.*;
    import java.io.*;

    // A class to represent a student.
    class Student {
        int rollno;
        String name;
        String address;

        // Constructor
        public Student(int rollno, String name, String address) {
            this.rollno = rollno;
            this.name = name;
            this.address = address;
        }

        // Used to print student details in main()
        public String toString(){
            return this.rollno + " " + this.name +
                               " " + this.address;
        }
    }

    class Sortbyroll implements Comparator<Student> {
        // Used for sorting in ascending order of rollno
        public int compare(Student a, Student b) {
            return a.rollno - b.rollno;
        }
    }

    class Sortbyname implements Comparator<Student> {
        // Used for sorting in ascending order of name
        public int compare(Student a, Student b) {
            return a.name.compareTo(b.name);
        }
    }

    // Driver class
    class Main {
        public static void main (String[] args) {
            ArrayList<Student> ar = new ArrayList<Student>();
           //here I have thousand student are inserted into 
           //simple collection.

            ar.add(new Student(111, "bbbb", "london"));
            ar.add(new Student(131, "aaaa", "nyc"));
            ar.add(new Student(121, "cccc", "jaipur"));

            System.out.println("Unsorted");
            for (int i=0; i<ar.size(); i++) {
                System.out.println(ar.get(i));
            }

            //collection sorted by rollno    
            Collections.sort(ar, new Sortbyroll());

            System.out.println("\nSorted by rollno");
            for (int i=0; i<ar.size(); i++) {
                System.out.println(ar.get(i));
            }

            //sort by Name
            Collections.sort(ar, new Sortbyname());

            System.out.println("\nSorted by name");
            for (int i=0; i<ar.size(); i++) {
                System.out.println(ar.get(i));
            }
        }
    }

Upvotes: 1

Views: 7063

Answers (3)

Siddharth Kumar
Siddharth Kumar

Reputation: 1

You can use a Trie data structure for autosuggestion implementation and the time complexity would be O(word_length) for insert and search.

Apache commons provides implementation "org.apache.commons.collections4.Trie"

example:

Trie<String, String> trie = new PatriciaTrie<>();

        trie.put("abcd", "abcd");
        trie.put("abc", "abc");
        trie.put("abef", "abef");

        SortedMap<String, String> map = trie.prefixMap("ab");

        map.forEach((k, v) -> {
            System.out.println(k + "  " + v);
        });

Upvotes: 0

user2194711
user2194711

Reputation: 161

Do refer https://github.com/nikcomestotalk/autosuggest/

This implementation is in java based on Patricia trie and Edit distance algorithm.

Some salient features of this application is

  1. Auto correction of keywords
  2. Bucket support for sorting and personalization support.
  3. Filtering support.
  4. Limit support.
  5. Build in http server.
  6. Blazing fast search.

And you all are welcome for feedback

Solr/Lucene/Elastic will not give freedom to choose algorithm and personalization support.

Upvotes: 0

Shafin Mahmud
Shafin Mahmud

Reputation: 4081

First of all your question is incomplete and misleading. It does not describes the requirement properly. But overall what I assume

You want Google like (?) suggester in your text box

It does not tell any specific things. What about your front end ? How about your data ?

Any way I think you just wanted to have a console like application where you will give partial String as input and your method will guess the Rest of String as an assumption from your dummy data. Am I right ?

If that is the thing you were looking for then I just sketched a demo code below

static List<String> query(String queryStr, List<Student> list) {
        List<String> suggestion = new ArrayList<>();
        list.forEach(std -> {
            if (isMatched(queryStr, String.valueOf(std.getRoll()))) {
                suggestion.add(String.valueOf(std.getRoll()));
            }

            if (isMatched(queryStr, std.getName())) {
                suggestion.add(std.getName());
            }

            if (isMatched(queryStr, std.getAddress())) {
                suggestion.add(std.getAddress());
            }
        });

        return suggestion;
    }

    private static boolean isMatched(String query, String text) {
        return text.toLowerCase().contains(query.toLowerCase());
    }

And what does this code do ? It actually takes the Partial String that the user input so far and your List<Student> as parameters. Then it iterates over the list and matches for all field for partial match. If any field matches the query it add that value in the suggestion list. In the main you can do like this :

public static void main(String[] args) {

        List<Student> list = new ArrayList<>();
        list.add(new Student(101, "Abc ghi", "USA"));
        list.add(new Student(102, "DEF", "UST"));
        list.add(new Student(103, "Ghi ab", "DSjkD"));
        list.add(new Student(104, "jKL ut", "USN"));
        list.add(new Student(105, "MNP", "TSA101"));
        list.add(new Student(106, "UTC ABC", "ESA"));

        List<String> sugg = query("01", list);
        sugg.forEach(System.out::println);
    }

and you will find the console printed like :

101
TSA101

Does it make sense ? it might not be your whole confusing requirements. But I think you got the idea. You can exploit this to address your own requirements. You could further imply your sorting logic or any kind of filters to it. It should not be that tough thing.

But you should be concerned that with large number of collection or complex associated objects this would not suffice. Real world application does not work this straight forward. You might need lot of other things to consider like memory, i/o and execution time.

Good Luck!

Upvotes: 3

Related Questions