Address book program in Java - java

I'm just doing a small program. It's an address book which has four options:
insert new contact
search contact by last name
delete contact by name
show all contacts
exit program
Just wondering how to get the insert contact part and how to store it. I've hardcoded one contact to test it.
Here is my code I have started
package addressbook;
import java.util.Scanner;
public class addressbooks
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
//create a table to hold information
String[][] addressbooks = new String[100][8];
addressbooks[0][0]="Mobile Number";
addressbooks[0][1]="First Name";
addressbooks[0][2]="Last Name";
addressbooks[0][3]="Address";
addressbooks[0][4]="City";
addressbooks[0][5]="County";
addressbooks[0][7]="Telephone Number";
//pre-populate address book for testing purposes and records
addressbooks[1][0]="1";
addressbooks[1][1]="David";
addressbooks[1][2]="Needham";
addressbooks[1][3]="Sraheens, Achill";
addressbooks[1][4]="Galway";
addressbooks[1][5]="Mayo";
addressbooks[1][6]="086-1581077";
addressbooks[1][7]="098-45368";
addressbooks[2][0]="2";
addressbooks[2][1]="Mc";
addressbooks[2][2]="lovin";
addressbooks[2][3]="Hawaii";
addressbooks[2][4]="Hawaii";
addressbooks[2][5]="Hawaii";
addressbooks[2][6]="12345";
addressbooks[2][7]="412-555-1234";
//menu options
System.out.print("Welcome to my Address book!");
System.out.print("\n");
System.out.print("\n1 - Insert a New Contact \n2 - Search Contact by Last Name \n3 - Delete Contact \n4 - Show All Contacts \n5 - Exit " );
System.out.print("\n");
System.out.print("\nChoose your option: ");
int option = input.nextInt();
if (option ==1)
{
System.out.print("\nPlease enter your First Name : ");
}
if (option ==2)
{
}
if (option ==3)
{
}
if (option ==4)
{
System.out.println(addressbooks[1][0]+
"\t"+addressbooks[1][2]+ ", "+addressbooks[1][1]+
"\n\t"+addressbooks[1][3]+
"\n\t"+addressbooks[1][4]+ ", "+addressbooks[1][5]+ " "+addressbooks[1][6]+
"\n\t"+addressbooks[1][7]);
}
if (option ==5)
{
}
}
}

I'd start like this:
package model;
public class Person {
private String firstName;
private String lastName;
// What else means something to your problem? Birthday?
// Constructors, getters (make them immutable), equals/hashCode
}
public class Address {
private String street;
private String city;
private String county;
private String postalCode;
// Constructors, getters (make them immutable), equals/hashCode
}
public class AddressBook {
private Map<Person, Address> contacts = new ConcurrentHashMap<Person, Address>();
public void addContact(Person p, Address a) {
this.contacts.put(p, a);
}
public void removeContact(Person p) {
this.contacts.remove(p);
}
public Collection<Person> findAllContacts() {
return new Collections.unmodifiableCollection(this.contacts.keySet());
}
public boolean hasContact(Person p) {
return this.contacts.contains(p);
}
// etc.
}
I would recommend separating all that stuff about text-based IO out away from the fundamentals of your problem. If you get it right, the next step is to write a web UI. Most of the code will be reusable if you do it correctly.
Think about layering your app:
view->services->persistence
Model classes might be used in all three layers.
The answer recommending JDBC isn't wrong. If you write your service and persistence classes as interfaces, you'll find it easy to swap out an in-memory Map of Contacts for a database version that uses JDBC:
package persistence;
public interface ContactDao {
Collection<Contact> find();
Contact find(Long id);
Collection<Contact> find(String lastName);
Collection<Contact> find(Address address);
Long save(Contact c);
void update(Contact c);
void delete(Contact c);
}
There are lots of ways to do things. I've already changed my mind: I've introduced a Contact class:
package model;
public class Contact {
private Person;
private Address;
}

The use of objects will greatly help you here:
class ADdressBook
{
List<Contact> contacts;
function addContact(Contact contact)
{
contacts.add(contact);
}
}
You will want to use the methods that are exposed as part of the List/Collection API to make this easier on you. Implementing the Contact class is an exercise for you.

I actually created a similar program, I would recommend simply constructing a database, this also allows you to save data in between uses of the program. Using JBDC is quite simple, here is the site i used: http://www.zentus.com/sqlitejdbc/

Related

Use an object in another class

I want to use the object person in the Librarian_Interface class, but this call the method login() in a loop. I think there is something I don't understand with java instance and I tried to get person with a constructor or methode but in vain. Thanks !
public class Login_Interface {
Person person;
public Login_Interface() {
db.initConnection();
person = login(db, in);
if (person != null)
{
Librarian_Interface a = new Librarian_Interface();
a.run();
}
}
public void run() {
}
public static Person login(DbConnection db, Scanner sc) {
Persons.setDbConnection(db);
Persons persons = Persons.getInstance();
System.out.print("\nEnter your Phone Number : ");
String phone = sc.nextLine();
System.out.print("\nEnter your Password : ");
String password = sc.nextLine();
return persons.login(phone, password);
}
}
public class Librarian_Interface {
public Librarian_Interface() {
// What I want
// System.out.print(person); or person.getAge(); ...
All you have to do is pass the person object to the Librarian_Interface constructor. then you can call methods getAge on it, etc.
public class Librarian implements Runnable {
private final Person person;
public Librarian(Person person) {
this.person = person;
}
#Override
public void run() {
int age = person.age();
// ... whatever else
}
}
By the way, the convention in Java is to use upper camel case for class names, with no underscores. So it would be better to name the class LibrarianInterface. Also, it's probably not the best idea to call it LibrarianInterface if it is in fact a class and not an interface.
Since Librarian has a public run method, it's a good idea to have it implement Runnable so that users of the class see how it is meant to be used.

How to save user choice into new array list

I’m sure I wasn’t clear enough in the title, clarifying everything here. I have a passenger booking a flight, I want to make a list in which the flights booked by the passenger will be stored.
This is the part of the code where the passenger completes the reservation, how do I make a new list and add a booked flight in it
#Override
public void payingFirstClassWithoutPromoCode(ArrayList<Flight> flightsList) {
System.out.println("Confirm buying ticket: (yes or no)");
String confirmation = scanner.nextLine();
if (confirmation.equalsIgnoreCase("yes")) {
if (selectedPassenger.getBalance() >= selectedFlight.getPriceForFirstClass()) {
System.out.println("Successful reserved!");
selectedPassenger.setBalance(selectedPassenger.getBalance() - selectedFlight.getPriceForFirstClass());
System.out.println(selectedPassenger.getFirstName() + "'s new balance is: " + selectedPassenger.getBalance());
} else {
noFundsAvailable(flightsList);
}
} else if (confirmation.equalsIgnoreCase("no")) {
cancellation(flightsList);
} else {
System.out.println("Wrong input!");
}
}
I think you can add a Flight field in your Passenger class, then do
selectedPassenger.setFlight(selectedFlight)
Here's the passenger class
class Passenger{
//other fields
Flight flight;
public void setFlight(Flight f){
this.flight = f;
}
If a passenger can have multiple flight, then declare a List in your passenger class, then do
selectedPassenger.getFlights().add(selectedFlight);
class Passenger{
//other fields
List<Flight> flight;
public Passenger(){
//don't forget to initialize flight list
flight = new ArrayList();
}
public List<Flight> getFlights(){
return this.flight ;
}
instead of fetching the whole list and adding it manually, you can have a method in your passenger class like
public void addFlight(Flight f){
this.flight.add(f);
}
then you can do
selectedPassenger.addFlight(selectedFlight);
You could design your Passenger class like this:
public class Passenger {
private String name;
private List<Flight> flights;
//Getter and setter for name
public Passenger(String name) {
this.name = name;
this.flights = new ArrayList<>();
}
public void addFlight(Flight flight) {
flights.add(flight);
}
}
On a side note, it might be worth refactoring your code. I note that you named your method payingFirstClassWithoutPromoCode(ArrayList<Flight> flightsList). I imagine you will have many more options, which means you will have to write multiple methods with very similar code.
It can be a good idea to make one method that can handle many different scenarios.
For example, you can add the ticket type (first/business/economy class) as an parameter in your method: payingWithoutPromoCode(ArrayList<Flight> flightsList, String ticketType).
It means you have to rewrite your method a little bit. In my example, you probably need to rewrite the methods in your Flight class. Instead of selectedFlight.getPriceForFirstClass() you can do selectedFlight.getPrice(ticketType).

Using strategy pattern along with Dependency injection

I'm going through Strategy pattern listed out in https://en.wikipedia.org/wiki/Strategy_pattern and trying to understand how this would work when you want to use Dependency injection as well and make it easy for unit testing.
So the interface is:
interface BillingStrategy {
// Use a price in cents to avoid floating point round-off error
int getActPrice(int rawPrice);
}
There are two implementations:
#Component
NormalHours implements BillingStrategy {
public int getActPrice(int rawPrice) {
return rawPrice;
}
}
#Component
HappyHours implements BillingStrategy {
public int getActPrice(int rawPrice) {
return rawPrice/2;
}
}
Now there is a customer object for whom I want to keep track of how the total price:
class Customer {
private final List<Integer> drinks = new ArrayList<>();
private BillingStrategy strategy;
public Customer(BillingStrategy strategy) {
this.strategy = strategy;
}
public void add(int price, int quantity) {
this.drinks.add(this.strategy.getActPrice(price*quantity));
}
// Payment of bill
public int getBill() {
int sum = this.drinks.stream().mapToInt(v -> v).sum();
this.drinks.clear();
return sum;
}
// Set Strategy
public void setStrategy(BillingStrategy strategy) {
this.strategy = strategy;
}
}
Now say I've a file which I've which has information about purchases made during each hour of the day, and I need to compute the final bill for the customer.
#Component
public class Calculator {
public int calculate(File file) {
//pseudo code here
Customer customer = new Customer();
for(line in file) {
//parse price, strategy and quantity from line
customer.setStrategy(strategy);
customer.add(price, quantity);
}
return customer.getBill();
}
}
Obviously this doesn't work great for unit testing as a new object is created within the method and by using just regular Mockito it's going to be hard to mock the values returned for the strategies in Calculator class. Is there a different way to model the Customer & Calculator class to ensure ease of testing and use DI as much as possible?
I know one way is let the caller of Calculator pass in the object Customer, but however with the way the wiki has explained this particular Customer class we cannot make it as a Singleton and the same problem will exist.
Given strategy isn't related to the Customer itself and placing it inside Customer is DI violation. Instead just pass strategy as method argument
class Customer {
private final List<Integer> drinks = new ArrayList<>();
public void add(BillingStrategy strategy, int price, int quantity) {
drinks.add(strategy.getActPrice(price * quantity));
}
// Payment of bill
public int getBill() {
int sum = drinks.stream().mapToInt(v -> v).sum();
drinks.clear();
return sum;
}
}
#Component
public class Calculator {
public int calculate(Customer customer, File file) {
//pseudo code here
for(line in file) {
//parse price, strategy and quantity from line
customer.add(strategy, price, quantity);
}
return customer.getBill();
}
}

Best way to store collection of objects in Java?

I am creating a dump Java app for student information system for learning and implementing OOPS Concepts like inheritance, abstraction, polymorphism and encapsulation.
What I am doing is, I have created Faculty Class, Student Class and a College Class. Now i want to add new faculty in College. So my approach is to create a method in College class i.e. addFaculty(Faculty f) and fireFaculty(Faculty f), now i want to add Faculties in College class.
Whats the best way to do it? How do i store list of Faculty Object in College Object. Because i can add more than one faculty and more than one student in college.
Whats the best approach to solve this problem in OOPS?
Here is College.java code which i have implemented, it works fine but is this the best way i can solve it?
public class College
{
String name;
String location;
String courses[];
HashMap<String,Faculty> faculties;
int noOfFaculties = 0;
int noOfStudents = 0;
public College(String name,String location,String courses[])
{
this.name = name;
this.location = location;
this.courses = courses;
faculties = new HashMap<>();
}
public void addFaculty(Faculty faculty)
{
faculties.put(faculty.getName(),faculty);
}
public void printFaculties()
{
Set<String> set = faculties.keySet();
if(set.size()>0)
{
for(String s:set)
{
System.out.println(faculties.get(s).getName());
}
}
else
{
System.out.println("No Faculties Currently Working");
}
}
public void fireFaculty(Faculty faculty)
{
faculties.remove(faculty.getName());
}
public String getName()
{
return name;
}
public String getLocation()
{
return location;
}
public String[] getCourses()
{
return courses;
}
}
If you cannot have duplicates use HashSet<Faculty> if you dont mind use a List<Faculty>.
Example:
class College {
private List<Faculty> listFactories = new ArrayList<>(); // dupes allowed
private Set<Faculty> setFactories = new HashSet<>(); // no dupes allowed
}
Check collections API.
There's a ton of ways you can do it. Probably the easiest way to handle storing a collection of objects is by using one of the Collections provided by Java. For beginners, probably the easiest one to understand is an ArrayList, which is basically an array that grows in size dynamically depending on the amount of objects in the collection.
So, as an axample, your code might be something like this:
public class College
{
private ArrayList<Faculty> faculty;
public College()
{
faculty = new ArrayList<Faculty>();
}
public void addFaculty(Faculty f)
{
faculty.add(f);
}
public void fireFaculty(Faculty f)
{
faculty.remove(f);
}
}
imho It depends what kind of services College college offers. If I were coding, I would start with:-
List<Faculy> faculties = new ArrayList<>();
....
public void addFaculty(Faculty f) {
faculties.add(f);
}
//... etc
And change to an altearnative later if needed.

Any nice way to make two immutable objects refer to eachother?

Take these two Java classes:
class User {
final Inventory inventory;
User (Inventory inv) {
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
Is there any way without using reflection* to pull this off? I don't actually expect it is, but it can't hurt to ask.
Update: Since in bytecode construction has two steps (1. allocate object, 2. call constructor**) could this be (ab)used to do this, with handwritten bytecode or a custom compiler? I'm talking about performing step 1 for both objects first, then step 2 for both, using references from step 1. Of course something like that would be rather cumbersome, and this part of the question is academic.
(* Because reflection may give trouble with a security manager)
(** Says my limited knowledge)
This can only work cleanly if one of the objects is created by the other. For example you can change your User class to something like this (while keeping the Inventory class unchanged):
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
You need to be careful about accessing the User object in the Inventory constructor, however: it's not fully initialized yet. For example, its inventory field will still be null!
Ad Update: I've now verified that the bytecode-manipulation approach does not work. I've tried it using Jasmin and it always failed to load with a VerifyError.
Delving deeper into the issue, I found§ 4.10.2.4 Instance Initialization Methods and Newly Created Objects. This section explains how the JVM ensures that only initialized object instances get passed around.
You can do it if you don't need to inject one of the objects.
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
class User {
private final Inventory inventory;
User (/*whatever additional args are needed to construct the inventory*/) {
//populate user fields
inventory = new Inventory(this);
}
}
class Inventory {
private final User owner;
Inventory (User own) {
owner = own;
}
}
That's the best I can think of. Maybe there's a better pattern.
Slightly pedantic, but it's not strictly speaking necessary to create one inside the other, if you don't mind a little indirection. They could both be inner classes.
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User() {
... has access to BadlyNamedClass.this.inventory;
};
this.inventory = new Inventory() {
... has access to BadlyNamedClass.this.owner;
};
}
...
}
Or even:
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User(this);
this.inventory = new Inventory(this);
}
public User getOwner() { return owner; }
public Inventory getInventory() { return inventory; }
...
}
This is one "solution", though the loss of one final is inconvenient.
class User {
Inventory inventory;
User () { }
// make sure this setter is only callable from where it should be,
// and is called only once at construction time
setInventory(inv) {
if (inventory != null) throw new IllegalStateException();
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
If you are only interested in JVM bytecode and don't care about coding in Java specifically, perhaps using Scala or Clojure could help. You'll need some kind of letrec machinery.
B: "Inventory created by the User is our last hope".
Y: "No, there is another."
If you abstract the references to a third party, you can control the relationship therein.
For example.
public class User
{
private final String identifier; // uniquely identifies this User instance.
public User(final String myIdentifier)
{
identifier = myIdentifier;
InventoryReferencer.registerBlammoUser(identifier); // Register the user with the Inventory referencer.
}
public Inventory getInventory()
{
return InventoryReferencer.getInventoryForUser(identifier);
}
}
public interface Inventory // Bam!
{
... nothing special.
}
// Assuming that the Inventory only makes sence in the context of a User (i.e. User must own Inventory).
public class InventoryReferencer
{
private static final Map<String, Inventory> referenceMap = new HashMap<String, Inventory>();
private InventoryReferencer()
{
throw ... some exception - helps limit instantiation.
}
public static void registerBlammoUser(final String identifier)
{
InventoryBlammo blammo = new InventoryBlammo();
referenceMap.add(indentifier, blammo);
}
public static void registerKapowUser(final String identifier)
{
InventoryBlammo kapow = new InventoryKapow();
referenceMap.add(indentifier, kapow);
}
public static Inentory getInfentoryForUser(final String identifier)
{
return referenceMap.get(identifier);
}
}
// Maybe package access constructors.
public class InventoryBlammo implements Inventory
{
// a Blammo style inventory.
}
public class InventoryKapow implements Inventory
{
// a Kapow style inventory.
}

Categories