My main goal is to identify if a number enters is not duplicated in the list, else user needs to update a new number. The system will keep asking user to enter non duplicate numbers.
I am currently struggling to get the logic in order to check if my List contains a duplicate ID. If someone inputs a duplicate ID, then he will be prompted to re-enter a new number. The new number will be checked again until the system satisfies with no duplicate element. The following function returns an integer, which will be added to the List of type Course in the main method.
The following is the snippet of my function:
public static int ifExist(List<Course> courselist, Iterator<Course> itr, int personid) {
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
boolean found = false;
boolean flag = false;
int personid2 = personid;
String value = null;
while (itr.hasNext()) {
Course courseItr = itr.next();
if(courseItr.getPersonID() == personid) {
found = true;
flag = true;
while(found == true) {
System.out.print("No duplicate number is accepted. Please enter another number: ");
do {
// must be a digit from 1 - 10,000
String digit = "\\d{1,10000}";
value = input.nextLine();
flag = value.matches(digit);
if (!flag) System.out.print("Please a number only!: ");
} while (!flag);
personid2 = Integer.parseInt(value);
if(personid2 != courseItr.getPersonID()) {
found= false;
}
}
}
}
return personid2;
}
The output while executing the Course program can be shown below. Note that entering no 1 means adding a course list.
Please select your choice: 1
Enter the person ID: 1
Enter the person name: Alysa
Enter the title of the course: Maths
Enter the year of joining: 2021
Enter the fee of the course: 20.50
New Course has successfully been added.
Please select your choice: 1
Enter the person ID: 1
No duplicate number is accepted. Please enter another number: 1
No duplicate number is accepted. Please enter another number: 1
No duplicate number is accepted. Please enter another number: 1
No duplicate number is accepted. Please enter another number: 2
Enter the person name: Maria
Enter the title of the course: Biology
Enter the year of joining: 2021
Enter the fee of the course: 25.99
New Course has successfully been added.
Please select your choice: 1
Enter the person ID: 2
No duplicate number is accepted. Please enter another number: 2
No duplicate number is accepted. Please enter another number: 2
No duplicate number is accepted. Please enter another number: 2
No duplicate number is accepted. Please enter another number: 1
Enter the person name: Peter
Enter the title of the course: Chemistry
Enter the year of joining: 2021
Enter the fee of the course: 50.50
New Course has successfully been added.
As shown in the above, it shows that my ifExist method is not working (trying to get the logic right). The two persons have the same ID, such 1.
When I tried to display the Course List
Please select your choice: 3
Person ID: 1, Name: Alysa, Title: Maths, Year: 2021, Fee: $20.5.
Person ID: 2, Name: Maria, Title: Biology, Year: 2021, Fee: $25.99.
Person ID: 1, Name: Peter, Title: Chemistry, Year: 2021, Fee: $50.5.
I have googled it, but it seems that I either have to use Set to remove any duplicates or use equals/hashcode(). Nevertheless, I would be highly appreciated if any experienced java programmer to help clarify or provide any idea on how to resolve this problem.
NEWLY ADDED METHOD
public static void addCourse(List<Course> courselist, Course course) {
//check if the id is the same or not
ListIterator<Course> itr = courselist.listIterator();
try {
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
int personid, year;
String author, title;
double fee;
System.out.print("\nEnter the person ID: ");
personid = input.nextInt();
personid = ifExist(booklist, itr, personid);
course.setPersonDd(personid);
...
...
...
courselist.add(new Course(personid, author, title, year, fee));
System.out.println("New Course has successfully been added.");
} catch {
}
}
Thank you. Look forward to hearing from fellow developers.
Regards,
Simone11
Regarding your first method
The problem lies in the iterator. When the user inputs 1 after 2, the iterator has already gone through the Course with the ID 1, so it is unable to detect duplicate IDs. Hence, every time the user inputs a new number, you must restart the iteration.
The List<Course> courselist parameter is unused.
With that said, this program is not logically optimized. The ifExists(,) method should solely work on searching for courses with the same ID. As for handling user input, it should be done completely outside of the method.
Here is an example of the ifExists(,) method
public static boolean ifExists(int id, Iterator<Course> iterator){
while (iterator.hasNext()) {
Course next = iterator.next();
if (next.id == id) return true;
}
return false;
}
Then in the main method, your messages to the user are based on the value returned by this method. Here is an example:
Scanner scanner = new Scanner(System.in);
int id = scanner.nextInt();
while (ifExists(id)) {
System.out.println("Duplicated ID! Please try another number.");
id = scanner.nextInt();
} // If ifExists(id) returns false, continue to the code below to enter personal details
Regarding your second method
Use HashSet instead of List or Iterator. You can directly call HashSet.contains(Obj) to check whether a Course already exists in the collection, without looping through the items. Even though List also has this method, it loops through all the items, which is similar to what you are doing.
This is because HashSet orders items by their hash code instead of the order of being added, but List doesn't. So when you call the contains method, it looks for entry no. (insert hash code).
Related
I'm trying to use an enhanced for loop to call a method many times in a row, but if I'm iterating more than once, the first iteration will only read the first line of code. Here are both of the methods I'm using:
public Account() {
this.subDetails = new HashMap<Integer, String>();
System.out.println("What is the account type? (Individual/Family)");
String planType = keyboard.nextLine();
System.out.println("Enter your card number: ");
this.cardNum = keyboard.nextLine();
System.out.println("Enter the expiration date: ");
this.cardExp = keyboard.nextLine();
if (planType.equals("Family")) {
System.out.println("How many users?");
int numUsers = keyboard.nextInt();
for (int z=0; z<numUsers; z++) {
this.addUser();
}
StreamingService.numFamUsers = StreamingService.numFamUsers + numUsers;
StreamingService.monthlyRevenue = StreamingService.monthlyRevenue + 14.99;
StreamingService.monthlyFamRevenue = StreamingService.monthlyFamRevenue + 14.99;
}
else if (planType.equals("Individual")) {
this.addUser();
StreamingService.numIndUsers++;
StreamingService.monthlyRevenue = StreamingService.monthlyRevenue + 9.99;
StreamingService.monthlyIndRevenue = StreamingService.monthlyIndRevenue + 9.99;
}
StreamingService.numAccounts++;
this.subDetails.put(i, planType);
i++;
}
public void addUser() {
System.out.println("What is the email of the next user?");
String e = keyboard.nextLine();
User y = new User(e, i);
StreamingService.userEmails.add(y);
StreamingService.numUsers++;
this.acctUsers.add(e);
}
And here is the output (Data quality is poor, just used as an example):
What is the account type? (Individual/Family)
Individual
Enter your card number:
1234123412341234
Enter the expiration date:
02/24
What is the email of the next user?
abc#def.com
What is the account type? (Individual/Family)
Family
Enter your card number:
1234123412341234
Enter the expiration date:
02/24
How many users?
3
What is the email of the next user? What is the email of the next
user?
abc#def.com
What is the email of the next user?
abc#defg.com
What is the account type? (Individual/Family)
Family
Enter your card number:
1234123412341234
Enter the expiration date:
02/24
How many users?
2
What is the email of the next user? What is the email of the next
user?
xyz#abc.com
Does anyone know how to fix this?
Scanner.nextInt does NOT consume the newline-charakter you enter after the nubmers. Because of this, any readline afterwards will consume the newline - and stop, becasue that's what it does.
Because of this, the first email prompt after entering the number of users will always return an empty string. You can see this in your output: it's the cases where the email prompt is duplicated.
To fix this, put a call to keyboard.nextLine() after all of your keyboard.nextInt() calls (and just ignore the output of that function).
I'm trying to prevent user to add 2 attendee with the same passport I tried many things as making Boolean variable to check if attendee was added before or no but I have failed all of my attempts can't really think of a way to make this
public class Test {
public static void main(String[] args) {
try {
Workshop Available_Work_Shops = new Workshop();
Scanner sc = new Scanner(System.in);
String passportNumber, workshop;
boolean isAttendeeMatch;
ArrayList<Attendee> attendeeList = new ArrayList<>();
int choice;
do {
System.out.println("1. Add New Attendee");
System.out.println("2. Add Existing Attendee to Workshop");
System.out.println("3. Remove Attendee from Workshop");
System.out.println("4. Print WorkShop List");
System.out.println("5. Print All Attendees");
System.out.println("0. Close Program");
System.out.println("Please Enter a number to choose");
choice = sc.nextInt();
sc.nextLine();
switch (choice) {
case 1 -> {
System.out.println();
System.out.println("Adding New Attendee");
System.out.println("____________________");
System.out.print("Please Enter Attendee Name: ");
String Attendee_name = sc.nextLine();
System.out.print("Please Enter Attendee Passport Number: ");
String Attendee_passport = sc.nextLine();
System.out.print("Please Enter Attendee Age: ");
String Attendee_Age = sc.nextLine();
System.out.print("Please Enter Attendee Phone Number: ");
String phone = sc.nextLine();
attendeeList.add(new Attendee(Attendee_name, Attendee_Age, Attendee_passport, phone));
for (Attendee attendee : attendeeList) {
if (attendeeList.contains(attendee.PassportNumber)) {
System.out.println("Existing User Found please enter '3' to remove the duplicate user");
}
}
}
The Issue
Let's focus on these two lines
...
for (Attendee attendee : attendeeList) {
if (attendeeList.contains(attendee.PassportNumber)) {
...
Since you've defined the attendeeList to be an ArrayList holding Attendee objects, you should be passing Attendee objects to attendeeList.contains(). While the contains() function does accept any Object, it will only return true if one of the List's elements .equals() the object you pass in.
The Solution
I'd recommend changing this block of code...
attendeeList.add(new Attendee(Attendee_name, Attendee_Age, Attendee_passport, phone));
for (Attendee attendee : attendeeList) {
if (attendeeList.contains(attendee.PassportNumber)) {
System.out.println("Existing User Found please enter '3' to remove the duplicate user");
}
}
... to something like this
Attendee potentialAttendee = new Attendee(Attendee_name, Attendee_Age, Attendee_passport, phone)
// Check if the potentialAttendee's passport number is already used by someone in the list.
boolean passportRegistered = false;
for (Attendee attendee : attendeeList) {
if (attendee.PassportNumber.equals(potentialAttendee.PassportNumber) {
System.out.println("That user passport number has already been registered. It can't be added again.");
passportRegistered = true;
}
}
// Only add the potentialAttendee if his/her passport number wasn't already used by someone in the list.
if (!passportRegistered) {
attendeeList.add(potentialAttendee);
}
The key difference is that you shouldn't add the potentialAttendee to the list until you've first validated that he/she meets the requirements to be added to that list.
Potential Enhancements
Store the Attendees in a HashMap instead of an ArrayList. If you key off of the PassportNumber, then by definition you can't have two participants with the same PassportNumber in the collection of attendees.
Java has a nice Streaming API that could make the validation even closer to a one liner.
Right off the bat, I see a few issues that would break the code:
You're adding the attendee to the list and then checking if it exists in the list afterwards (which it always will after adding it if checking correctly).
if (attendeeList.contains(attendee.PassportNumber)) will never return true because you're checking if the entire List has an object that is equal to the PassportNumber in it (as opposed to the PassportNumber in the object). It should be if(attendee.getPassportNumber().equals(Attendee_passport)).
Not sure how much of a beginner you are but it might also be useful to look into things like naming conventions (in general Java variables should be named with a lowercase first letter and each new word has an uppercase letter), using List<Attendee> as the declared variable type instead of ArrayList, and things like filtering lists using Java Streams to see if something exists already. Java also has Set as an alternative to List for when you only want to store unique values (there's other differences between List and Set so make sure you look into it if you want to use it).
I am trying to have users input a UNIQUE value for a book's ISBN.
I am able to receive user input and it populates the ArrayList just fine, but if a user inputs a value that is already in the ArrayList, I want them to receive an error message and be prompted to try again.
do{
System.out.print("\n ISBN must be 4 numbers only.\nEnter isbn: ");
isbn = sc.nextLine();
try{
isbnInt = Integer.valueOf(isbn);
}//end try
catch(NumberFormatException nfe){
System.out.println("\nPlease enter integer numbers only.");
}//end catch
}while(isbn.trim().length() <4 && (isbn.trim().length()>0) || (isbn.trim().length() >4));
sc = new Scanner(System.in);
System.out.println();
do{
System.out.print("Enter quantity: ");
quantity = sc.nextLine();
try{
quantityInt = Integer.valueOf(quantity);
}//end try
catch(NumberFormatException nfe){
System.out.println("\nPlease enter integer numbers from 1 through 1000 only.");
}//end catch
}while(quantity.trim().length() > 1000 ||(quantity.trim().length()<0) );
Create a method to validate ISBN such as
public boolean verifyISBN(int ISBN)
Here you will check if ISBN exists in the arraylist by using a for loop
Upon receiving the return value store it in a variable and use in while condition of 1st do-while loop.
I think you're in need of a different data structure, like HashSet, because it doesn't allow duplicates.
When calling the add method:
hashSet.add(quantityInt);
It verifies if the HashSet already contains that element.
if it contains: it'll not insert the element and will return false;
if it doesn't contain: it'll insert the element and will return true.
You can check if the method returned false and if so, show an error message and enable the input again.
...
final Set<Integer> set = new HashSet<>();
int quantityInt = scanner.nextInt();
while(!set.add(quantityInt)) {
System.out.println("You can't insert duplicate elements.");
quantityInt = scanner.nextInt();
}
...
I feel like I am dialing in on it. Unfortunately I am required to use an ArrayList for the assignment.
I have a while loop setup with a boolean operator "contains"
while(contains != books.contains(isbnInt)){
But it isn't working
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 4 years ago.
I am currently learning Java programming using an Udemy course (Complete Java Masterclass by Tim Bulchalka to be exact) and am learning ArrayList.
I am trying to program an app to behave like an mobile phone, in which it can contain contact numbers.
Here is my main src(or what do you call it?), minus some irrelevant (or codes which encounter the same problem):
package com.timbuchalka;
import java.util.Scanner;
public class Main {
private static Scanner scanner2 = new Scanner(System.in);
public static void main(String[] args) {
MobilePhone phone = new MobilePhone();
boolean quit = false;
int choice = 0;
printInstructions();
while(!quit) {
System.out.println("What do you want to do?");
choice = scanner2.nextInt();
scanner2.nextLine();
switch (choice) {
case 1:
phone.printContact();
break;
case 2:
phone.addContact();
break;
........
case 7:
quit = true;
break;
}
}
}
public static void printInstructions() {
System.out.println("\nPress ");
System.out.println("\t 0 - To see instructions again.");
System.out.println("\t 1 - To see all contacts.");
System.out.println("\t 2 - To add new contact.");
......
System.out.println("\t 7 - To quit the application.");
}
}
Here is my Contacts class (within MobilePhone class):
package com.timbuchalka;
import java.util.ArrayList;
import java.util.Scanner;
public class Contacts {
private static Scanner scanner = new Scanner(System.in);
private ArrayList<Integer> listPhoneNumber = new ArrayList<Integer>();
private ArrayList<String> listName = new ArrayList<String>();
public void addContact() {
System.out.println("Please enter the contact name: ");
String name = scanner.nextLine();
System.out.println("Please enter the contact number: ");
int number = scanner.nextInt();
addContact(name, number);
}
public void printContacts() {
System.out.println("Contact Details:");
for (int i=0; i<listPhoneNumber.size(); i++) {
System.out.println((i+1) + ". " + listName.get(i) + " - " + listPhoneNumber.get(i));
}
System.out.println("\t");
}
private void addContact(String name, int number) {
listName.add(name);
listPhoneNumber.add(number);
}
When going through the application, the 1st round works fine. I can print and/or add a contact to the my Contacts class. However, when I try to add another contact, I am unable to input the Contact Name. The console skips straight to inputting inputting the Contact Number instead. Here is an example:
Press
0 - To see instructions again.
1 - To see all contacts.
2 - To add new contact.
3 - To modify a contact's name.
4 - To modify a contact's number.
5 - To remove a contact's details.
6 - To search for a contact's details.
7 - To quit the application.
What do you want to do?
1
Contact Details:
What do you want to do?
2
Please enter the contact name: //the 1st time it doesn't skip this step
John
Please enter the contact number:
12345
What do you want to do?
2
Please enter the contact name: // however during the 2nd time, this step is skipped
Please enter the contact number:
3
What do you want to do?
1
Contact Details:
1. John - 12345
2. - 3
May I know why is this happening? And also, may I know how do I resolve this issue? Thank you very much!
When reading from a Scanner I find it best to always use nextLine() and then manually parse the data.
This allows you to consistently consume whole lines of data. And you can more carefully parse the user input.
So, in your case, instead of reading the option using nextInt(), you'd use nextLine() and then Integer.parseInt().
Every time you call scanner.nextInt() follow it with scanner.nextLine() so that the end of line token is swallowed.
I'm making a program that gives you a menu:
1. Show all records.
2. Delete the current record
3. Change the first name in the current record
4. Change the last name in the current record
5. Add a new record
6. Change the phone number in the current record
7. Add a deposit to the current balance in the current record
8. Make a withdrawal from the current record if sufficient funds are available.
9. Select a record from the record list to become the current record.
10. Quit
and a command promt:
Enter a command from the list above (q to quit):
I have 4 Linked Lists:
firstName
lastName
teleNumber
accountBalance
I'm sure you can assume what they contain...
Assume I have already added a new record.
I'm trying to figure out how to make a method that would keep a node selected as I make changes or remove it.
public void numberNine()
{
System.out.println("Enter first name: ");
String fName = keyboard.next();
System.out.println("Enter last name: ");
String lName = keyboard.next();
if(firstName.contains(fName))
{
if(lastName.contains(lName))
{
/*I need to set the current record here.
I also need to print out the current record.
That means I need to find the corresponding
information from the linked lists by checking
the index of the first or last name because
both share the same index position for the
correhlating information of the selected person
for the current record.*/
}
else
{
System.out.println("No matching record found.");
}
}
else
{
System.out.println("No matching record found.");
}
}
The only thing is that I'm not completely familiar with the syntax to perform to get the job done, but from what I've come understand after looking around, I might need a method that looks somewhat like this:
public void currentRecord(String fName, String lName)
{
/*check for index of both fName and lName between the two strings containing
this information until they match up, then select the telenumber and
balance that match the index of the fName and lName and print*/
}
I've understood the explanations I have found, but there hasn't been any syntax with these explanations to assist me in actually achieving this. Could someone please show me how it's done?
private static void searchRecord(String firstName, String lastName) {
boolean recordFound = false;
if(fName.contains(firstName) && lName.contains(lastName)){
int index = -1;
for (String fn : fName) {
index++;
if(fn.equals(firstName)){
String ln = lName.get(index);
if(ln.equals(lastName)){
recordFound = true;
System.out.println("Record Found");
System.out.println("First Name="+ fName.get(index));
System.out.println("Last Name="+ lName.get(index));
System.out.println("Phone="+ phone.get(index));
System.out.println("Balance="+ balance.get(index));
}
}
}
}
if(!recordFound) {
System.out.println("No Record found for first name="+ firstName + " and last name="+lastName);
}
}