Arvind Suryanarayana
Arvind Suryanarayana

Reputation: 247

Adding a condition to accept specific entries in HashMap

My program is a Simple Student Management Database which collects the name, subject and phone numbers of students and adds to a database. I've been able to achieve the main logical operations like adding, deleting and searching students in the database. I'm unable to restrict students to enter only approved subjects like for example "English", "Maths" and "Computing" when adding into a HashMap collection. Any help would be appreciated. Here's the main code:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.Scanner;

public class Menu {
    private HashMap<String, Student> students;

    public Menu() {
        students = new HashMap<String, Student>();
    }

    private void eventLoop() {
        Scanner scanner = new Scanner(System.in);
        int choice = 0;
        boolean exit = false;
        this.readFromFile();

        while (!exit) {
            System.out.println("Welcome to Student Management System");
            System.out.println("==============================");
            System.out.println("(1) Add new student");
            System.out.println("(2) Delete a student");
            System.out.println("(3) Find Student By Name");
            System.out.println("(4) List Students By Subject");
            System.out.println("(5) List All Students");
            System.out.println("(6) Exit System");
            System.out.println("Choose an option: ");

            try {
                choice = Integer.parseInt(scanner.nextLine());
                System.out.print('\u000C');
                if (choice < 1 || choice > 6) {
                    System.err.println("Error : Choose an option between 1 and 6");
                    choice = 0;
                }
            } catch (NumberFormatException e) {
                System.err.println("Error : Choose an option between 1 and 6");
                choice = 0;
            }

            switch (choice) {
                case 1:
                this.addStudent(scanner);
                break;
                case 2:
                this.deleteStudent(scanner);
                break;
                case 3:
                this.findStudentByName(scanner);
                break;
                case 4:
                this.findStudentsBySubject(scanner);
                break;
                case 5:
                this.listStudents();
                break;
                case 6:
                this.writeToFile();
                exit = true;
            }
        }
        scanner.close();
    }

    private void findStudentsBySubject(Scanner scanner) {
        System.out.println("Enter the exact name of the subject:");
        String subjectStr = scanner.nextLine();
        boolean atleastOne = false;
        for (String name : students.keySet()) {
            if (students.get(name).getSubject().getName().toLowerCase().equals(subjectStr.toLowerCase())) {
                System.out.println(students.get(name));
                atleastOne = true;
            }
        }
        if (!atleastOne) {
            System.err.println("No students have enrolled for this subject.");
        }
    }

    private void findStudentByName(Scanner scanner) {
        System.out.println("Enter the exact name of the Student to search:");
        String name = scanner.nextLine();
        if (students.get(name.toLowerCase()) != null) {
            System.out.println("Student details:");
            System.out.println(students.get(name.toLowerCase()));
        } else {
            System.err.println(name + " not found in the database.");
        }
    }

    private void deleteStudent(Scanner scanner) {
        System.out.println("Enter the exact name of the Student to delete:");
        String name = scanner.nextLine();
        if (students.get(name.toLowerCase()) != null) {
            students.remove(name.toLowerCase());
            System.err.println("Student " + name + " deleted from the database.");
        } else {
            System.err.println(name + " not found in the database.");
        }
    }

    private void addStudent(Scanner scanner) {
        System.out.println("The information should be comma separated and in a single line.");
        System.out.println("If the name is not unique, the system will throw an error.");
        System.out.println("Enter the name, phone and subject of the new student.");

        String line = scanner.nextLine();
        System.out.print('\u000C');
        String[] info = line.split(",");
        if (info.length != 3) {
            System.err.println("Please enter the information in the proper format.");
            return;
        }
        String name = info[0];
        String phone = info[1];
        String subjectStr = info[2];

        if (students.get(name.toLowerCase()) != null) {
            System.err.println("This student already exists in the database.");
            return;
        }
        if (phone.length() != 9) {
            System.err.println("The phone number must contain exactly 9 digits.");
            return;
        }
        if (phone.charAt(0) != '9') {
            System.err.println("The phone number must start with '9'.");
            return;
        }
        if (!phone.matches("^[0-9]*$")) {
            System.err.println("The phone number must contain only numbers.");
            return;
        }
        students.put(name.toLowerCase(), new Student(name, new Subject(subjectStr), phone));
        System.err.println("Student added successfully");
    }

    private void listStudents() {
        for (String name : this.students.keySet()) {
            System.out.println(this.students.get(name));
        }
    }

    private void readFromFile() {
        try {
            BufferedReader br = new BufferedReader(new FileReader(new File("./students.txt")));
            String line;
            while ((line = br.readLine()) != null) {
                String[] info = line.split(",");
                String name = info[0];
                String phone = info[1];
                String subjectName = info[2];

                if (students.get(name.toLowerCase()) == null) {
                    Subject subject = new Subject(subjectName);
                    students.put(name.toLowerCase(), new Student(name, subject, phone));
                } else {
                    System.err.println("There seems to be a duplicate student in the file.");
                }
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void writeToFile() {
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(new File("./students.txt")));
            for (String name : students.keySet()) {
                bw.write(students.get(name).toString());
                bw.newLine();
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Menu menu = new Menu();
        menu.eventLoop();
    }

}

Subject Class:

public class Subject {
    private String name;
    public Subject(String subjectName) {
        this.setName(subjectName);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return this.getName();
    }
}

Upvotes: 1

Views: 72

Answers (2)

Peter Lawrey
Peter Lawrey

Reputation: 533720

When you have a restricted list of possible values you can use an Enum e.g.

enum Subject {
    English, Maths, Computing
}

A collection of these is just an EnumSet and you can check it's value by calling

EnumSet<Subject> subjects = EnumSet.of(Subject.class);

Subject s = Subject.valueOf(subjectName);
subjects.add(s);

Upvotes: 1

Keshan Nageswaran
Keshan Nageswaran

Reputation: 8188

Using stream and filter you can easily achieve this

                 students.entrySet()
                         .stream()
                         .filter(.. some predicate...)
                         .map(Map.Entry::getValue)
                         .collect(Collectors.toList())

If you are sure you are going to get at most a single element that passed the filter (which is guaranteed by your filter), you can use findFirst :

Optional<List> o = students.entrySet()
                      .stream()
                      .filter( e -> e.getKey() == 1)
                      .map(Map.Entry::getValue)
                      .findFirst();

In the general case, if the filter may match multiple Lists, you can collect them to a List of Lists :

List<List> list = students.entrySet()
                     .stream()
                     .filter(.. some predicate...)
                     .map(Map.Entry::getValue)
                     .collect(Collectors.toList());

Upvotes: 1

Related Questions