Calling the info from one class to another class? - java

I am relatively new to programming and an working with setters and getters at the moment.
I have something set up where I have a student class that has information about said student, including their first, middle, and last name, their student ID, and their major.
I need to set it so that, if their student ID is less than zero, it automatically sets it to -1. I also need to set the major to undecided if they do not input anything.
I also need to override the toString method and print all of this information out.
I feel like I have the first part with the names down, I am not sure about the rest of it however. I am not sure how I am supposed to use the toString method while also using setters and getters.
Below is my Student class that does all of the work.
import java.util.Objects;
import java.util.Scanner;
public class Student {
String first;
String middle;
String last;
String major = "Undecided";
static int studentID = -1;
public Student(String first, String middle, String last) {
Objects.requireNonNull(first);
Objects.requireNonNull(last);
}
public void setFirst(String A) {
first = A;
}
public void setMiddle(String B) {
middle = B;
}
public void setLast(String C) {
last = C;
}
private String getFirst() {
return first;
}
private String getMiddle() {
return middle;
}
private String getLast() {
return last;
}
private String getMajor() {
return major;
}
public void setMajor(){
static void register(int a){
if (a < 0) {
studentID = a;
} else {
studentID = getID(a);
}
}
private static int getID(int a) {
if (studentIDInput < 0) {
studentID = -1;
} else {
studentID = a;
}
return studentID;
}
public static void main(String[] args) {
String first = "abc";
String middle = "def";
String last = "ghi";
Scanner sc = new Scanner(System.in);
String majorInput = sc.next();
int studentIDInput = sc.nextInt();
Student student1 = new Student(first, middle, last);
System.out.println(student1.getFirst().toString() + " " + student1.getMiddle().toString() + " " + student1.getLast().toString() + '\n' + "Major:" + " " + student1.getMajor().toString() + '\n' );
}
#Override
public String toString() {
return ;
}
}
I have also included the Driver class just for reference.
public class Driver {
static String first;
static String middle;
static String last;
public static void main(String[] args){
Student student1 = new Student(first, middle, last);
student1.setFirst("Mikayla");
student1.setMiddle("Rose");
student1.setLast("Knox");
}
}

You have this constructor:
public Student(String first, String middle, String last) {
Objects.requireNonNull(first);
Objects.requireNonNull(last);
}
It does its job of checking that first and last name are not null, but it does not do anything with the values besides checking. The constructor's job is to construct the object, i.e, initialize its member variables. When your constructor is done, you should have a usable object, without having to call any setters in it.
You need to add that:
public Student(String first, String middle, String last) {
Objects.requireNonNull(first);
Objects.requireNonNull(last);
this.first = first;
this.middle = middle;
this.last = last;
}
Note that you don't need to use setters here as code within the class can access member variables directly. You can use setters if you want, though.
As for toString: this is a method mainly used in debugging, and it displays some helpful information about the object it's called on. You could implement it like below, with a bit of ?: to make sure to only print the middle name if it's not null:
#Override
public String toString() {
return first + " " + (middle != null ? middle + " " : "") + last;
}
I'll leave it to you to also include major and ID.
On using a Scanner: You use a Scanner to get input from somewhere, like the from the user. You don't need it in toString or any setters or getters. These are all methods that should be very simple and not deal with I/O classes like Scanner.

If you are using constructors, you do not really need setters. Try something like this:
class Student {
private String first;
private String middle;
private String last;
private String major;
private int studentID;
public Student(String first, String middle, String last) {
this(first, middle, last, "undecided", -1);
}
public Student(String first, String middle, String last, String major, int studentID) {
this.first = first;
this.middle = middle;
this.last = last;
this.major = major;
this.studentID = studentID;
}
#Override
public String toString() {
return "first: " + first + "\nmiddle: " + middle + "\nlast: " + last + "\nmajor: " + major + "\nid: " _ studentID;
}
}
This way, when you create a new Student object with 3 parameters, the last 2 are automatically set to "undecided" and -1. If there is a case when you have the ID and not the major (or the other way around), you can add more constructors.

Related

Referencing the array variables in the Reference class, sorting it using another method, and invoking the sorted values in the case statement

I am trying to call the array variables in the reference class, try to sort them using a user-defined method and call the method onto the case statement that will be invoked if the user chooses a particular number. I wanted to provide the user the option what attribute of a student will be sorted (i.e. name, course...) and show the sorted one dimensional array called in the case statements and invoked through the main method.
Here's the variables in the Reference class:
class RecordReference {
private int idNumber;
private String firstName = "";
private String middleName = "";
private String lastName = "";
private int age;
private String yearLevel;
private String course = "";
private double gwa;
public RecordReference(int i, String f, String m, String l, int a, String y, String c, double g) {
idNumber = i;
firstName = f;
middleName = m;
lastName = l;
age = a;
yearLevel = y;
course = c;
gwa = g;
}
public int getIdNumber() {
return idNumber;
}
public String getFirstName() {
return firstName;
}
public String getMiddleName() {
return middleName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getYearLevel() {
return yearLevel;
}
public String getCourse() {
return course;
}
public double getGwa() {
return gwa;
}
public void setIdNumber(int idnumber) {
idNumber = idnumber;
}
public void setFirstName(String fName) {
firstName = fName;
}
public void setMiddleName(String mName) {
middleName= mName;
}
public void setLastNameName(String lName) {
lastName= lName;
}
public void setAge(int a) {
age = a;
}
public void setYearLevel(String yLevel) {
yearLevel = yLevel;
}
public void setCourse(String c) {
course = c;
}
public void setGwa(int gwa) {
gwa = gwa;
}
public String toString() {
return String.valueOf(System.out.printf("%-15s%-15s%-15d%-15d%n",
firstName, course , yearLevel ,gwa));
}
} // end of class
And I am trying to call it in this sort method, but I don't know how to reference it.
public static void sortFirstNameArray(String[] f){
for (int i = 0; i < f.length - 1; i++) {
for (int j = i + 1; j < f.length; j++) {
if (f[i].compareToIgnoreCase(f[j]) > 0) {
String temp = f[i];
f[i] = f[j];
f[j] = temp;
}
}
}
}
After the sorting is successfully done, I'll call it in a switch case statements that will be invoked once the user chooses a particular number. This part has 5 case statements (Name, Age, Course, General Weighted Average and the option to sort it all - I plan to add more student attributes if this works)
(I don't know if I should store this in another method and call it in the main method or just put it in the main method like that)
public RecordReference Process(RecordReference[] f, RecordReference[] a) {
// for loop?
for (int x = 0; x < f.length; x++) {
switch (choice) {
case 1:
System.out.println("Sorted array of first name: ");
sortFirstNameArray(f[x].getFirstName());
System.out.printf("%-15s%n", Arrays.toString(f));
break;
case 2:
System.out.println("Sorted array of age: ");
// invokes the age method
sortAgeArray(a[x].getAge());
System.out.printf("%-15s%n", Arrays.toString(a));
break;
}
}
}
If it is in another method, what param do I include when I call it in the main method?
I tried this but it doesn't work, I don't know what to do
System.out.print("Please choose what student attribute you want to
sort :");
choice = keyboard.nextInt();
// calling the process method here, but I receive syntax error
Process(f,a); // Here, I want to pass the sorted values back into the array but I get an error.
If you can help me out that would be great. Thank you in advance.
I'm just a first year student and I am eager to learn in solving this error.
It's good to see that you have attempted the problem yourself and corrected your question to make it clearer, because of that I am willing to help out.
I have tried to keep the solution to the problem as close to your solution as possible, so that you are able to understand it. There may be better ways of solving this problem but that is not the focus here.
First of all, let's create a class named BubbleSorter that will hold methods for sorting:
public class BubbleSorter
{
//Explicitly provide an empty constructor for good practice.
public BubbleSorter(){}
//Method that accepts a variable of type RecordReference[], sorts the
//Array based on the firstName variable within each RecordReference
//and returns a sorted RecordReference[].
public RecordReference[] SortByFirstName(RecordReference[] recordReferencesList)
{
for (int i = 0; i < recordReferencesList.length - 1; i++) {
for (int j = i + 1; j < recordReferencesList.length; j++) {
if (recordReferencesList[i].getFirstName().compareToIgnoreCase
(recordReferencesList[j].getFirstName()) > 0) {
RecordReference temp = recordReferencesList[i];
recordReferencesList[i] = recordReferencesList[j];
recordReferencesList[j] = temp;
}
}
}
return recordReferencesList;
}
}
That gives us a class that we can instantiate, where methods can be added to be used for sorting. I have added one of those methods which takes a RecordReference[] as a parameter and sorts the RecordReference[] based on the firstName class variable within each RecordReference. You will need to add more of your own methods for sorting other class variables.
Now for the main class:
class Main {
public static void main(String[] args) {
//Get a mock array from the GetMockArray() function.
RecordReference[] refArray = GetMockArray();
//Instantiate an instance of BubbleSorter.
BubbleSorter sorter = new BubbleSorter();
//Invoke the SortByFirstName method contained within the BubbleSorter
//and store the sorted array in a variable of type RecordReference[] named
//sortedResult.
RecordReference[] sortedResult = sorter.SortByFirstName(refArray);
//Print out the results in the sorted array to check if they are in the correct
//order.
//This for loop is not required and is just so that we can see within the
//console what order the objects in the sortedResult are in.
for(int i = 0; i < sortedResult.length; i++)
{
System.out.println(sortedResult[i].getFirstName());
}
}
public static RecordReference[] GetMockArray()
{
//Instantiate a few RecordReferences with a different parameter for
//the firstName in each reference.
RecordReference ref1 = new RecordReference(0, "Ada", "Test", "Test", 22, "First",
"Computer Science", 1.0f);
RecordReference ref2 = new RecordReference(0, "Bob", "Test", "Test", 22, "First",
"Computer Science", 1.0f);
RecordReference ref3 = new RecordReference(0, "David", "Test", "Test", 22,
"First", "Computer Science", 1.0f);
//Create a variable of type RecordReference[] and add the RecordReferences
//Instantiated above in the wrong order alphabetically (Based on their firstName)
//class variables.
RecordReference[] refArray = {
ref2, ref3, ref1
};
return refArray;
}
}
In the main class I have provided verbose comments to explain exactly what is happening. One thing I would like to point out is that I have added a method named GetMockArray(). This is just in place to provide a RecordReference[] for testing and you probably want to do that somewhere else of your choosing.
If anything is not clear or you need some more assistance then just comment on this answer and I will try to help you further.
Thanks.

Read File to Print to Screen

I have a file Inventory.txt that I am trying to print to the screen. Each line from the file goes into an object array. My code compiles with no errors but when I run it, nothing prints nothing to the screen. Im using Mac and TextEdit/Terminal.
import java.util.Scanner;
import java.io.*;
public class VendingMachineSimulator
{
to be imported
public static void main(String[] args) throws FileNotFoundException
{
File InventoryFile = new File("Inventory.txt");
Scanner input = new Scanner(InventoryFile);
//This code block will count the number of lines(products) are in the text file
int counter = 0;
while (input.hasNextLine())
{
counter = counter + 1;
}
Inventory[] InventoryObject = new Inventory[counter];
String line = "";
for (int i = 0; i < counter; i++)
{
String[] ProductArray = line.split("-");
InventoryObject[i] = new Inventory(Integer.valueOf(ProductArray[0]), ProductArray[1], ProductArray[2],
ProductArray[3],Double.valueOf(ProductArray[4]), ProductArray[5],
Integer.valueOf(ProductArray[6]));
}
for (int i = 0; i < counter; i++)
{
System.out.println();
InventoryObject[i].PrintInventory();
}
}
public static void PrintMenu()
{
System.out.println();
System.out.println("Display Inventory: <1>");
System.out.println("Display Currency: <2>");
System.out.println("Purchase Item: <3>");
System.out.println("Exit: <4>");
System.out.println();
}
}
class Inventory
{
private int ID;
private String Type;
private String Name;
private String PriceText;
private double Cost;
private String QuantityText;
private int StockAmount;
//Constructor method. values passed to it from the main method.
public Inventory(int ID, String Type, String Name, String PriceText, double Cost, String QuantityText, int StockAmount)
{
this.ID = ID;
this.Type = Type;
this.Name = Name;
this.PriceText = PriceText;
this.Cost = Cost;
this.QuantityText = QuantityText;
this.StockAmount = StockAmount;
}
public void setID(int ID)
{
this.ID = ID;
}
public void setType(String Type)
{
this.Type = Type;
}
public void setName(String Name)
{
this.Name = Name;
}
public void setPriceText(String PriceText)
{
this.PriceText = PriceText;
}
public void setCost(double Cost)
{
this.Cost = Cost;
}
public void setQuantityText(String QuantityText)
{
this.QuantityText = QuantityText;
}
public void setStockAmount(int StockAmount)
{
this.StockAmount = StockAmount;
}
public int getID()
{
return ID;
}
public String getType()
{
return Type;
}
public String getName()
{
return Name;
}
public String getPriceText()
{
return PriceText;
}
public double getCost()
{
return Cost;
}
public String getQuantityText()
{
return QuantityText;
}
public int getStockAmount()
{
return StockAmount;
}
public void PrintInventory()
{
System.out.println(ID + " " + Type + " " + Name + " " + PriceText
+ " " + Cost + " " + QuantityText + " " + StockAmount);
}
}
You never read a line, you only count them:
while (input.hasNextLine())
{
counter = counter + 1;
}
You have to place line = input.readLine(); inside this loop somewhere and change your logic accordingly, otherwise, it will always stay in the while loop. Think about when you would need to update or read the counter.
This is an endless loop. If there is text in the file, the input has a next line.
Since that line isn't read in the loop, input.hasNextLine() is always true.
while (input.hasNextLine())
{
counter = counter + 1;
}
You should rather use a List to read the Objects, that way you don't need to know the size initially.
You can remove the first while loop as its infinite loop.
Change the for loop to a while loop and do itererate as long as you have a next line and within the loop read the nextline and assign to line string and change the inventoryObject to an ArrayList and add items.
This should ideally resolve the issue.
You are blocking the input from the Inventory.txt file in you while loop. You are only checking if a next line exists without actually reading the next line. So you're going to an infinite loop here:
int counter = 0;
while (input.hasNextLine())
{
counter = counter + 1;
}
You need to call this at some point inside your whilte loop:
input.nextLine();
Tip: You can consolidate all the actions that you are performing inside this while loop. You probably don't need as many loops:
Assigning to line; Declare line before the while loop.
Splitting line into ProductArray. This will be line.split assigned to ProductArray.
Creating the new Inventory object. You may not need an array of Inventory Objects. Simply create one using the ProductArray variable.
Printing the inventory. Simply call the PrintInventory method on the the object created in step 3.
Hope this helps!

Remove element of arraylist from user's input

I need to remove an element from an ArrayList using user's input.
Not really asking for a solution, but more of a guide in the right direction.
public class BFFHelper
{
ArrayList<BestFriends> myBFFs;
Scanner keyboard = new Scanner(System.in);
public BFFHelper()
{
myBFFs = new ArrayList<BestFriends>();
}
public void addABFF()
{
System.out.println("Enter a first name: ");
String firstName = keyboard.next();
System.out.println("Enter a last name: ");
String lastName = keyboard.next();
System.out.println("Enter a nick name: ");
String nickName = keyboard.next();
System.out.println("Enter a phone number: ");
String cellPhone = keyboard.next();
BestFriends aBFF = new BestFriends(firstName, lastName, nickName, cellPhone);
myBFFs.add(aBFF);
}
public void changeABFF()
{
System.out.println("I am in changeBFF");
}
public void removeABFF()
{
//System.out.println("I am in removeABFF");
System.out.print("Enter friend's name to remove: ");
int i = 0;
boolean found = false;
while (i<myBFFs.size() && !found)
{
if (myBFFs.get(1).getfirstName().equalsIgnoreCase(firstName)) && (myBFFs.get(1).hetlastName().equalsIgnoreCase(lastName))
i++
}
}
public void displayABFF()
{
System.out.println("My Best Friends Phonebook is: ");
System.out.println(myBFFs);
}
}
this is what i have for my main class
public class BestFriends {
private static int friendNumber = 0;
private int friendIdNumber;
private String firstName;
private String lastName;
private String nickName;
private String cellPhoneNumber;
public BestFriends (String aFirstName, String aLastName, String aNickName, String aCellPhone)
{
firstName = aFirstName;
lastName = aLastName;
nickName = aNickName;
cellPhoneNumber = aCellPhone;
friendIdNumber = ++friendNumber;
}
public String getFirstName()
{
return firstName;
}
public String getLastName()
{
return lastName;
}
public String getNickName()
{
return nickName;
}
public String getCellPhone()
{
return cellPhoneNumber;
}
public int getFriendId()
{
return friendIdNumber;
}
public String toString()
{
return friendIdNumber + ". " + firstName + " (" + nickName + ") " + lastName + "\n" + cellPhoneNumber + "\n";
}
}
Elements can be removed from an ArrayList using in various ways, for example by calling list.remove(index); or alternatively, by simply specifying the object to remove.
Just study the Javadoc for those methods. In addition to that, there are calls like removeAll() that remove all the arguments provided to the call.
Side note: there is at least one bug in your code:
if (myBFFs.get(1).getfirstName().equalsIgnoreCase(firstName)) && (myBFFs.get(1).hetlastName().equalsIgnoreCase(lastName))
should probably read.
if (myBFFs.get(i).getfirstName().equalsIgnoreCase(firstName)) && (myBFFs.get(i).hetlastName().equalsIgnoreCase(lastName))
Assuming that you are looping with i for a reason; and that you don't want to compare element1 to itself all the time.
And while we are at it: you could improve your abstractions. Obviously your program is about "humans". Humans normally have fixed names, haven't they. Meaning: have a class that just represents a human being; with final fields for information that can't change. Such fields are initialized via the constructor; and you dont have any setters for those.
How to Remove element of ArrayList from user's input?
One way to do such thing is to use an Iterator and call remove() when you find a match, something like this:
// Iterate over the list myBFFs
for (Iterator<BestFriends> it = myBFFs.iterator(); it.hasNext();) {
BestFriends bf = it.next();
if (/*some test here*/) {
// Found a match to remove
it.remove();
// Exit from the loop
// To be added if and only if you expect only one match otherwise keep iterating
break;
}
}
Assuming that you use Java 8, you can rely on the Stream API for such need.
In case you want to remove the first match
myBFFs.stream().filter(bf -> /*some test here*/).findFirst().ifPresent(myBFFs::remove);
This approach uses List#remove(Object o) to remove a unique object.
In case you want to remove all matches
myBFFs.removeAll(
myBFFs.stream().filter(bf -> /*some test here*/).collect(Collectors.toList())
);
This approach uses List#removeAll(Collection c) to remove a collection of objects.

array of string in java

I want to solve this problem without using arraylist.
i want to add the contact to its specific index in the array of strings. And then display all the added contacts in string format seperated by commas.
My code gives the result of only last added contract:
Contact [first=Bob, last=Moore, number=555-9756]
where is the problem in my code?
Is there any idea how to solve???
This class consist of the main method:
This is the main class:
public class ExampleApp {
public static void main(String[] args) {
PhoneBook pb = new PhoneBook("Personal book");
System.out.println( pb.getName() );
pb.add("Alice", "Green", "555-1234");
pb.add("Mary", "Smith", "555-6784");
pb.add("Bob", "Moore", "555-9756");
System.out.println( pb.toString() );// here i want to display all the contracts seperated by commas
System.out.println( pb.first() );// first contract
System.out.println( pb.get(2) );// second contract
String toBeFound = new String("Moore");
System.out.println( pb.find(toBeFound) );// display the found contract
}
}
This is the phonebook class:
public class PhoneBook {
public static final int MAX = 10;
public String name;
String[] contracts = new String[MAX]; // i created an array of strings
Contact c;
/**
* Create a new phonebook with given name
*/
public PhoneBook(String name) {
this.name = name;
}
/**
* Return the phonebook name
*/
public String getName() {
return name;
}
/**
* Insert a new contact at the end
*/
public void add(String first, String last, String number){
c=new Contact(first,last,number);
for(int i=0;i<MAX;i++){ // i added for each array index the contracts strings
contracts[i]= c.toString();
}
}
/**
* Return the first contact
*/
public String first() {
return get(1);
}
/**
* Return the i-th contact (supposing that first
* index is 1)
*/
public String get(int i) {
String s =contracts[i].toString();
return s;
}
/**
* Return a string containing the list of textual
* representation of all contacts, separated by ", ".
* List starts with "("and ends with ")"
*/
public String toString() {
String s= " ";
for(int i=1;i<MAX;i++){ // here i tried to display the string looping the array
s=contracts[i].toString();
}
return s;
}
/**
* Return the textual representation of first
* contact containing "needle"
*/
public String find(String needle) {
//TODO: to be implemented
return null;
}
}
This is the contact class :
public class Contact {
public String first;
public String last;
public String number;
public String[] contacts;
public Contact(String first, String last, String number) {
this.first=first;
this.last = last;
this.number=number;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
#Override
public String toString() {
return "Contact [first=" + first + ", last=" + last + ", number="
+ number + "]";
}
}
You can use ArrayList for it. It will help you really much and you should make your veriables private.
private String first;
private String last;
private String number;
private ArrayList<String> list = new ArrayList<String>();
for(String pointer : list){
}
or you can make contact saver ArrayList
private ArrayList<Contact> list = new ArrayList<Contact>();
public Contact(String first, String last, String number) {
this.first=first;
this.last = last;
this.number=number;
}
public void add(String first, String last, String number){
c=new Contact(first,last,number);
list.add(c);
}
and you can access all veriables like that list.get(i).first.
You can save your contact class and contracts array in arraylist and it will give you more power to access. If you want to display your ArrayList, which index is not important, you need only ++i for it.
I changed your class look this:
public class PhoneBook {
public static final int MAX = 10;
public String name;
String[] contracts = new String[MAX]; // i created an array of strings
Contact c;
private int count = 0;// saved last index of array
public PhoneBook(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void add(String first, String last, String number) {
c = new Contact(first, last, number);
contracts[count] = c.toString(); // save your String inside of last index++
count++;
}
public String first() {
return get(1);
}
public String get(int i) {
String s = contracts[i].toString();
return s;
}
public String toString() {
for (int i = 0; i < MAX; i++) {
if (contracts[i] != null)
System.out.println(contracts[i].toString());
}
return "";
}
public String find(String needle) {
return null;
}
}
public class Contact {
public String first;
public String last;
public String number;
public Contact(String first, String last, String number) {
this.first = first;
this.last = last;
this.number = number;
}
#Override
public String toString() {
return "Contact [first=" + first + ", last=" + last + ", number="
+ number + "]";
}
}
//Personal book
//Contact [first=Alice, last=Green, number=555-1234]
//Contact[first=Mary, last=Smith, number=555-6784]
//Contact [first=Bob, last=Moore, number=555-9756]
you always delete your last toString method. Your Add method is wrong. You always turn 0 and write again inside of array.
You should keep track of the last contact added to your array :
private int lastIndex = 0; // index of first available index of the array
...
/**
* Insert a new contact at the end
*/
public void add(String first, String last, String number){
c=new Contact(first,last,number);
if (lastIndex < MAX)
contracts[lastIndex++]= c.toString();
}
Some other issues with your code :
/**
* Return the first contact
*/
public String first() {
return get(1); // should be get(0)
}
Calling toString() for contracts[i] is redundant, since it's already a String. Perhaps you meant to store Contact instances instead of Strings in your array? That would make more sense.
Add an extra variable static int Last = 0; To track how many contact you have added and update the add function as .
public void add(String first, String last, String number){
if(Last>=MAX){
System.out.println("Error in adding\n");
}
else{
c=new Contact(first,last,number);
contacts[Last] = c.toString();
Last++;
}
}
Change Tostring() for loop to last. So that you will be printing only added contact .In your case you are printing upto MAX that is wrong when less no of contacts are added.
You have to pass i=0,1,2,...,MAX-1 to get(i) function . Array is Zero(0) based indexed.
So, the problem you are having is that you always retrieve the last contact, regardless of which one you try to get. This is because when you add a new contact, you are actually replacing ALL the contacts, making them all the same. You are getting the correct contact from the phonebook, but they ALL have the same value.
To fix it, do the following:
public class PhoneBook
{
int contactsAdded = 0; // Add an integer to store how many contacts you have added
Contact[] contacts = new Contact[MAX]; //Change this to Contact array, not string
//Contact c; //You can remove this line
//Rest of your code
}
public void add(String first, String last, String number)
{
//Only add if the number of contacts is less than the max
if (contactsAdded < MAX)
{
//Construct the new contact when you use it.
contacts[contactsAdded] = new Contact(first, last, number);
contactsAdded++;
}
}
Not sure if I understood all of your code right, but I think you are overwriting all other contacts in your phone book:
public void add(String first, String last, String number){
c=new Contact(first,last,number); //(1)
for(int i=0;i<MAX;i++){ //(2)
contracts[i]= c.toString();
}
}
At position (1) a new Contact object is created and assigned to c. In the next step (2), you loop through the array and assign the info contained in c (the latest contact added) to all already entries in the contracts array.
Independent from your problem, I suggest that you replace the array of a fixed size with i.e. an ArrayList of type Contact. Adding entries to this list, iterating, sorting etc is very easy.

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.
Try java's collection, e.g. 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;
}
}
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.

Categories

Resources