Design Q&A application as in Amazon has it for each product


  • 5

    Design Q&A as you see in Amazon, Walmart website for an item.

    How about this?

    public class QnA {
      ArrayList<Question> questions;
      ArrayList<Answers> answers;
      ArrayList<Items> items;
      QnA() {
        this.questions = new ArrayList<Question>();
        this.answers = new ArrayList<Answers>();
        this.items = new ArrayList<Answers>();
      }
    
      boolean PostQuestion(int itemId, String ques) {
        try {
          Item item = items.get(itemId);
          Question q = new Question(itemId, ques);
          this.questions.add(q);
        } catch (IndexOutOfBoundException) {
          return false;
        }
        return true;
      }
      
      boolean PostAnswer(int qid, int itemId, String ques) {
        try {
          Question q = questions.get(qid); 
          Answer a = new Answer(qid, itemId, ques);
          this.questions.add(q);
          q.ans.add(a);
        } catch (IndexOutOfBoundException) {
          return false;
        }
        return true;
      }
      // upvoteQuestion()
      // upvoteAnswer()
    }
    
    class Question {
      int itemId;
      string ques;
      static int qctr = 0;
      int id;
      ArrayList<Answers> ans;
      Question(int itemId, String ques) {
        this.id = qctr++;
        this.ques = ques;
        this.itemId = itemId;
        this.ans = new ArrayList<Answers>();
      }
    }
    
    class Answer {
      int qid;
      int id;
      String ans;
      static int actr = 0;
      int itemId;
      Answer(int qid, int itemId, String ans) {
        this.id = actr++;
        this.itemId = itemId;
        this.ans = ans;
      }
    }
    
    class Item {
      ArrayList<Question> qs;
    }
    
    main() {
      QnA qna = new QnA();
      if(!qna.postQuestion(1, "what is the product price")) {
        System.out.println("Invalid Item Id");
      }
      if (!qna.postAnswer(1, 1, "its 19.4")) {
        System.out.println("Invalid Question Id");
      }
    }
    

    Inputs will be greatly appreciated.
    Thanks in advance.


  • 2
    R

    I am using maps to keep a track of question / answer list. Gets are fast. I am sorting when a question or answer is upvoted / added. (Not sure if thats the optimized approach). Any feedback is much appreciated.

    
    import java.util.*;
    
    public class OOPDesignQnA {
    
        Map<Question, Map<Integer, Answer>> questionAnswerMap;
    
    
        Map<Integer, Question> questionMap;
        Map<Integer, Map<Integer, Question>> productQnAMap;
        Map<Integer, List<Question>> productQuestions;
    
        public OOPDesignQnA(){
            this.questionMap = new TreeMap<>();
            this.productQnAMap = new TreeMap<>();
        }
    
    
        public void addQuestion(String text, Integer productId, Integer userId){
            Question question = new Question(productId, text, userId);
            questionMap.put(question.id, question);
            productQnAMap.put(productId, questionMap);
            if(productQuestions.containsKey(productId)) {
                List<Question> list = productQuestions.get(productId);
                list.add(question);
                Collections.sort(list);
            }else{
                List<Question> questions = new ArrayList<>();
                questions.add(question);
                productQuestions.put(productId, questions);
            }
        }
    
        public void addAnswer(Integer productId, Integer questionId, String text, Integer userId){
            Answer answer = new Answer(questionId, productId, text, userId);
            Question question = questionMap.get(questionId);
            List<Answer> answerList = question.answerList;
            answerList.add(answer);
            Collections.sort(answerList);
    
            if(questionAnswerMap.containsKey(question)){
                questionAnswerMap.get(question).put(answer.id, answer);
            }else{
                Map<Integer, Answer> answerMap = new HashMap<>();
                answerMap.put(answer.id, answer);
                questionAnswerMap.put(question, answerMap);
            }
        }
    
        public List<Question> getAllQuestions(Integer productId){
            return productQuestions.get(productId);
        }
    
        public List<Answer> getAnswersforQuestions(Integer productId, Integer questionId){
            Map<Integer, Question> qMap = productQnAMap.get(productId);
            return qMap.get(questionId).answerList;
        }
    
        public void upvoteQuestion(Integer productId, Integer questionId){
            Map<Integer, Question> qMap = productQnAMap.get(productId);
            qMap.get(questionId).upvotes += 1;
            List<Question> questions = productQuestions.get(productId);
            Collections.sort(questions);
        }
    
        public void upvoteAnswer(Integer productId, Integer questionId, Integer answerId){
            Map<Integer, Question> qMap = productQnAMap.get(productId);
            Question question = qMap.get(questionId);
            Answer answer = questionAnswerMap.get(question).get(answerId);
            answer.upvotes += 1;
            Collections.sort(question.answerList);
        }
    
    
    
    }
    
    class Question implements Comparable<Question>{
    
        static Integer count = 0;
    
        Integer id;
        Integer productId;
        String text;
        Integer userId;
        List<Answer> answerList;
        Integer upvotes;
        Date createdAt;
    
    
        public Question(Integer productId, String text, Integer userId){
            this.productId = productId;
            this.text = text;
            this.userId= userId;
            this.id = count++;
            answerList = new ArrayList<>();
            this.upvotes = 0;
            this.createdAt = new Date();
        }
    
        @Override
        public int compareTo(Question o) {
            if(this.upvotes == o.upvotes){
                return createdAt.compareTo(o.createdAt);
            }else{
                return this.upvotes.compareTo(o.upvotes);
            }
        }
    
    }
    
    
    class Answer implements Comparable<Answer>{
    
        static Integer count = 0;
    
        Integer id; // Do I need this ?
        Integer questionId;
        Integer productId;
        Integer userId;
        String text;
        Integer upvotes;
        Date createdAt;
    
    
        public Answer(Integer questionId, Integer productId, String text, Integer userId){
            this.questionId = questionId;
            this.productId = productId;
            this.text = text;
            this.userId = userId;
            this.id = count++;
            this.upvotes = 0;
            this.createdAt = new Date();
        }
    
        @Override
        public int compareTo(Answer o) {
            if(this.upvotes == o.upvotes){
                return createdAt.compareTo(o.createdAt);
            }else{
                return this.upvotes.compareTo(o.upvotes);
            }
        }
    }
    

  • 0
    S

    @randome_coder thanks for the reply.
    Using map is the better way to go.
    Do we need to go into this much detail in actual interview? Any thoughts?
    But code is always good.

    Another issue ... what if there are millions of question? Do we need to store them in db and write code for that too?


  • 1
    D

    The Whole Q&A object is child class that parent product (or itemID) class uses.

    I believe ArrayList<Items> items; does not belong in this class, but instead it belongs to its parent class for items , which uses this Q&A class. This class keeps a data member for itemID, and will be stored in implicit object first time this classes object is instantiated with appropriate constructor.
    Also, all the post Questions and Post Answer function does not need item Id, as it is implied for the same object, once that object contextualized.
    (For this Q&A object can and does belong to one unique product ItemId.)
    bolded text


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.