So I have an issue with Hashmaps and a login feature.
When using addLogin I am required to enter parameters but it makes no sense to do this since I have already done this in the constructor classes. How would I simply just use addLogin and the Surname, Forename and Personal ID number is added to the hashmap?
Upon using Math.round(Math.random()*999+1) to generate a random number between 1-999 how am I supposed to go around adding this to the hashmap with the other student details?
Here is the full code that applies to both questions, apologies for the stupid questions I'm very new to Java! I am very appreciative of any help I recieve. Thanks in advance.
public class TestApplication
{
// hashmap
private HashMap<String, ArrayList <String>> Application = new HashMap<String, ArrayList <String>>();
// hashset
private HashSet<String> loginsIssued = new HashSet<String>();
// An Arry List for storing student information
private ArrayList<String> Student = new ArrayList<String>();
/**
* Constructor for objects of class Application
*/
public TestApplication(String Surname, String personalIdNo)
{
if (isValidpersonalIdNo(personalIdNo) == true)
{
Student.add(Surname);
Application.put(personalIdNo, Student);
System.out.println("Application number ### " + "has registered successfully");
}
else
{
System.out.println("Application has failed, Personal id: " + personalIdNo);
}
}
/**
* Create a Student Information
*/
public void TestApplication(String personalIdNo, String Surname, String Forename)
{
Student.add(Surname);
Student.add(Forename);
Student.add (personalIdNo);
}
/**
* Add Login
* Pull First Letter of Forenames
* Pull First Letter of Surname
* Generate Random Number
* Print
*/
public void addLogin(String Surname, String Forename)
{
String login = "";
{
System.out.println (Surname.charAt(0) + "" + " " + Forename.charAt(0) + " " + Math.round(Math.random()*999+1));
Student.add(login);
loginsIssued.add(login);
}
}
/**
* CONDITION 1
* Check whether the ID supplied is only numbers
*/
public boolean isNumeric(String personalIdNo)
{
if (personalIdNo.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) {
return true;
}
else
{
return false;
}
}
/**
* CONDITION 2
* Check whether the ID supplied has a length of 10
*/
public boolean checkLength(String personalIdNo)
{
if (String.valueOf(personalIdNo).length()==10)
{
return true;
}
else
{
return false;
}
}
/**
* CONDITION 3
* Check whether the ID supplied starts with 1
*/
public boolean checkFirstDigit(String personalIdNo)
{
if (personalIdNo.startsWith("1"))
{
return true;
}
else
{
return false;
}
}
/**
* Validation Check - Check if it satisfies all conditions.
*/
public boolean isValidpersonalIdNo(String personalIdNo)
{
if (isNumeric(personalIdNo) && checkLength(personalIdNo) && checkFirstDigit(personalIdNo))
{
return true;
}
else
{
return false;
}
}
/**
* FORENAME
* Add Forename
*/
public void addForename(String Forename)
{
Student.add(Forename);
}
/**
* Return Surname
*/
public String getSurname()
{
return Student.get(0);
}
}
Concerning to your first question
At the initialisation i guess you just want to give the string a value normally you achieve this through writing
String login= null;
But I'm quiet not sure what you want to achieve with the empty ""
And i dont get why you dont give your login a value before you add it to the arraylist or should be this the login by default
public void addLogin(String Surname, String Forename)
String login = null;
{
System.out.println (Surname.charAt(0) + "" + " " + Forename.charAt(0) + " " + Math.round(Math.random()*999+1));
Student.add(login);
loginsIssued.add(login);
}
And just as a tip if you return boolean at your equalization methods you dont need to check in the if clauses if true == true because the if clause checks if you do it your way wether true ==true and returns true if it like this do you get my point? you 'll save resources if you dont do this twice :)
So just write your method which returns the boolean value in the if braces .
I hope i can help you
Pls comment if you need further informations
To be honest, I think there should be some rework to fix your code (sorry to not answer directly to you two questions but is impossible as is):
Fix the second constructor, which is declared as a method
Create a Student class: it is harder to retrieve fields by index and the risk is to add twice the same field or to miss adding one field.
Unless I don't fully understand what your code should achieve, the major issue is a design error : your TestApplication class manages the whole set of students and their login thus the Student instance variable is a nonsense as well as the constructors with a single student fields. You should instead create an addStudent method with the student fields as parameter or better a Student instance.
I don't understand the use of "" + " " either.
By consequence, to answer to your questions:
You can keep your addLogin method and if so, yes you have to keep all the info but you can use a Student object (or a Collection as you currently modelise a student) as parameter.
If you update the same Student (same object instance), it is of course updated in your map. If not(you use a copy of Student) then just execute Application.put(personId,Student). Have a look at this answer to get more info
Related
I'm hoping someone can help me out with a question that I've been stuck on for quite a while.
Just to clarify the scenario. There is a show being held in a theatre that can hold 180 people. They allow online bookings that are written to a text file "bookings.txt" Individual bookings are single that only have a seat, contact and payment status record. Whereas group bookings have seats, a contact number, payment status, group name and group size records.
So far I have created the Bookings and GroupBookings classes. I'll show them below:
/**
*
* #author OP
*/
public class Booking
{
public String seat;
public String contact;
public double cost;
public boolean paid;
//Constructor
public Booking(String st, String ct, int cost, boolean pd)
{
seat = st;
contact = ct;
this.cost = cost;
paid = pd;
}//end of Booking
//Getters
public String getSeat()
{
return seat;
}//end of getSeat
public String getContact()
{
return contact;
}//end of getContact
public boolean isPaid()
{
return paid;
}//end of isPaid
public double getCost()
{
//Determining what discount should be applied to their seat location
if (seat.contains("A") || seat.contains("B") ||
seat.contains("C") || seat.contains("D"))
{
cost = 200;
}
else
{
if (seat.contains("E") || seat.contains("F") ||
seat.contains("G") || seat.contains("H"))
{
cost = 160;
}
else
{
if (seat.contains("I") || seat.contains("J") ||
seat.contains("K") || seat.contains("L"))
{
cost = 120;
}
}
}//end of nested if statement
return cost;
}//end of getCost
#Override
public String toString()
{
return seat + "\t" + "R" + cost + "\t" + paid;
}//end of toString
}//end of class booking
/**
*
* #author OP
*/
public class GroupBooking extends Booking
{
private String groupName;
private int groupSize;
public GroupBooking(String st, String ct, boolean pd, String gn, int gs)
{
//Variables from previous class (using inheritance)
super.seat = st;
super.contact = ct;
super.paid = pd;
//New variables for this class
groupName = gn;
groupSize = gs;
}//end of GroupBooking
#Override
public double getCost()
{
cost = super.getCost();
for (int i = 0; groupSize % 4 > i; i++)
{
cost = cost - 60;
i++;
}//end of for loop
return cost;
}//end of getCost
public int getGroupSize()
{
return groupSize;
}//end of getGroupSize
public String getGroupName()
{
return groupName;
}//end of getGroupName
#Override
public String toString()
{
return seat + "\t" + "R" + cost + "\t" + groupName;
}//end of toString
}//end of class GroupBooking
Now for the question that I am stuck on:
A new class has to be created called BookingManager. From there I have to declare two instance variables in the class of one-dimensional array that can be used to store up to 180 Booking or GroupBooking objects. An integer counter must also be created to keep track of how many Bookings are stored in the array. (These two instance variables should not be accessible from outside the class)
I'm still a newbie in coding and I'm unsure of what to do here. The follow-up question is also giving me difficulties:
A contractor then has to be created to read the information from the text file "bookings.txt". Each line either contains a single Booking or a GroupBooking object. Read each line from the file and instantiate the appropriate type of object (Booking or GroupBooking) and add it to the array. (Note in the case of GroupBooking you must create an object in the array for each member of the group. Exp for a group of six you have to have six separate GroupBooking objects in the array.)
I know a file scanner is needed from the second question but I have no idea whether to use a for loop or an if statement to differentiate between a single booking or a group booking.
If anyone can help I would truly appreciate it. This topic is still very new to me.
To prevent a variable being accessible outside a class declare the variable "private". e.g.
private String costtotal="";
An instance variable "is not" static ("is not" a class member variable), and are a global variable only declared at the top of the class code below the import statements, so exist until the class exits.
In your manager class you need a global variable array Booking class
Booking[] bookings;
private String costtotal=""; // e.g.
// in the constructor read the bookings file and find the number of bookings made
//int totalbooked=...whatever reading the file data counts to of bookings made;
bookings=new Booking[totalbooked];
// create and fill each Booking object and assign it to its index on the array in a loop
bookings[loopcount]=new Booking(st,ct,cost,pd);
Different schemes of class systematics of coding
// bean syntax in a java bean framework class type
public void setCosttotal(String costtotal){
this.costtotal=costtotal;
}
//bean syntax
public String getCosttotal(){
return costtotal;
}
// normal non bean syntax 1
public String costTotal(String csttot){
return (String)csttot;
}
// somewhere else in code in scope to global variable
costtotal=costTotal(valuein);
// normal non bean syntax 2
public String costTotal(String csttot){
costtotal=csttot;
return costtotal;
}
I have two classes, one named Bird the other Runtime. The bird class creates birds - name, latin name. The Runtime class has 4 methods, only one is important for this question, that is the 'add' method. The add method when called upon needs to take input from the user that is name and latin name, these are saved into a string variable 'name' and 'latin name' and I call the Bird class constructor and pass in these string variables into its parameter and finally it is added to an ArrayList. However I get duplicate values, if I were to write the same bird twice.
I have tried to convert the ArrayList into a set and convert it back again into an ArrayList, i did this within the add method, this did not work. I suspect it is down to my poor understanding of how objects are stored in an ArrayList. I also created a getName method within the Bird class, so I can use list.get(i).getName, and if the name is equal to the one typed by the user, it prompts the user accordingly, if not it is added to my ArrayList. This also did not work. I also tried a for loop that would go through the ArrayList and an if statement would determine if the name typed by the user exists within the ArrayList, this also did not work, the attempt was early on so I can't remember exactly the error message, but the add method is called from within a while loop, and I think the error message was concurrent modification, I'm not entirely sure so please ignore that, my point is showing the various solutions I tried.
Below is The Bird class
public class Bird{
int obeservation = 0;
String name;
String latinName;
public Bird(String name, String latinName){
this.name = name;
this.latinName = latinName;
}
public void addBird(String name, String latinName){
this.name = name;
this.latinName = latinName;
}
public String getName(){
return this.name;
}
public String statistics(){
return this.name + " (" + this.latinName + ") : " +
this.obeservation + " observation";
}
}
Below is the Runtime class
public class Runtime {
ArrayList<Bird> birds = new ArrayList<Bird>();
Scanner scan = new Scanner(System.in);
public void scan() {
System.out.println("?");
String answer = scan.nextLine().trim();
while (!answer.equalsIgnoreCase("EXIT")) {
System.out.println("?");
answer = scan.nextLine().trim().toUpperCase();
if (answer.equalsIgnoreCase("ADD")) {
add();
} else if (answer.equalsIgnoreCase("OBSERVATION")) {
observation();
} else if (answer.equalsIgnoreCase("STATISTICS")) {
System.out.println("jhjh");//just to see if this is
working
statistics();
}
}
}
below is the add method, also what I've commented is the attempts,
currently the add method does not have an if statements to decide duplicates.
public void add() {
System.out.print("Name: ");
String name1 = scan.nextLine().trim().toUpperCase();
System.out.print("Latin Name: ");
String latinName1 = scan.nextLine().trim().toUpperCase();
birds.add(new Bird(name1, latinName1));
/*
Bird newBird = new Bird(name1, latinName1);
for (int i = 0; i < birds.size(); i++) {
if (birds.get(i).getName().equals(name)) {
System.out.println("Bird already exist");
return;
} else {
birds.add(newBird);
}
}
/*
* hBirds.addAll(birds); birds = new ArrayList<Bird>();
birds.addAll(hBirds);
*
* // Bird newBird = new Bird(name, latinName);
* /* if(birds.contains(name)){
* System.out.println("That name already exist");
* return;
* }else{
* birds.add(newBird(name, latinName));
*
* }
*/
}
The statistics method prints out the ArrayList, a foreach loop that goes through the ArrayList prints it out. The expected result if I input seagull twice should be one seagull value not two. How do i reject the duplicate?
You can have two approaches here:
First: Traverse through ArrayList, if you can't find the same bird, add it to ArrayList. It is a worse approach.
Second: Store birds inside HashSet. In this case, you need to override .hashCode() and .equals(Object obj) methods. It is a better approach.
Before talking about how to generate .hashCode() and .equals(Object obj) methods, I want to mention about .hashCode() method and HashSet<T>.
HashSet<T>s provide a unique set of the elements inside. To achieve this, .hashCode() method of a class is used. If you override .hashCode() method in any class, you can get the benefit of using HashSet<T>s. If you don't override this method, Java automatically returns the memory address of the object. That's why your HashSet<Bird> was including duplicate elements.
.hashCode() and .equals() methods can be generated by lots of IDEs. I copied and pasted your Bird class to Eclipse. By using Alt+Shift+S -> h for Eclipse or Alt+Insert -> equals() and hashCode() for IntelliJ, automatically generated the methods below:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((latinName == null) ? 0 : latinName.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + obeservation;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Bird other = (Bird) obj;
if (latinName == null) {
if (other.latinName != null)
return false;
} else if (!latinName.equals(other.latinName))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (obeservation != other.obeservation)
return false;
return true;
}
If you add these methods(I encourage you to generate in your IDE) to Bird class, you can use HashSet<Bird>. To avoid duplicates, simply add all of your Bird objects into defined HashSet<Bird>. You don't need any other data structure or equality check to control if any two Bird type objects are equal.
You will just need to change your object collection from ArrayList<Bird> birds = new ArrayList<Bird>(); to Set<Bird> birds = new HashSet<>();.
Move the add out of the loop:
for (int i = 0; i < birds.size(); i++) {
if (birds.get(i).getName().equals(name1)) {
System.out.println("Bird already exist");
return;
}
}
birds.add(new Bird(name1, latinName1));
I am attempting to write a program which asks users what their pet name is, species, finds out thirst level and gives a response accordingly.
I would appreciate if someone could help me with a problem im having, in each of the 2 methods askpetname and thirstlevel there are 2 strings i want accessible throughout the entire class without using global variables.
Can someone tell me what it is i am doing incorrectly or point me in the right direction.
Also, i understand that my excess use of methods for tedious tasks is bad practice but it helps with memorising syntax.
Thanks.
class dinoo
{
public static void main(String[] p)
{
explain();
output();
System.exit(0);
}
public static void explain()
{
print("The following program demonstrates use of user input by asking for pet name.");
return;
}
public static String askpetname()
{
Scanner scanner = new Scanner(System.in);
print("Name your dinosaur pet!");
String petname = scanner.nextLine();
print("Awesome, cool dinosaur name, what species is " + petname+ " ?");
String petspecies = scanner.nextLine();
return petname, petspecies;
}
public static int thirstlevel()
{
Random ran = new Random();
int thirst = ran.nextInt(11);
int hunger = ran.nextInt(11);
return thirst,hunger;
}
public static String anger(int thirst, int hunger)
{
double angerscore = (thirst+hunger)/2;
String temper;
if(angerscore<=2)
{
temper = "Serene";
}
else if(3<=angerscore<=6)
{
temper= "Grouchy";
}
else if(6<angerscore)
{
temper = "DANGEROUS";
}
return temper;
}
public static String warning()
{
if (temper.equals("Serene"))
{
print("He's looking happy!");
}
else if(temper.equals("Grouchy"))
{
print("Ahhh hes a bit "+temper+", you better start feeding him before he gets mad!");
}
else if(temper.equals("DANGEROUS"))
{
print("GET OUT OF THERE, HES " + temper+"!!!. He will have to be put down for everyones safety.");
}
}
public static void output()
{
print(askpetname() + "'s, thirst level is "+thirstlevel()+"/10");
return;
}
public static String print(String message)
{
System.out.println(message);
return message;
}
}
That code won't compile since you can't have:
return string1, string2;
or
else if(3<=angerscore<=6)
Instead of trying to return multiple Strings, your best bet is to create a class, say called Pet, one that holds String fields for the pet's name, a Species field for its species, as well as any other fields for hunger, thirst ... that would best encapsulate all the data that makes up one logical "pet" as well as a methods such as getAnger() that returns a value for anger depending on the Pet's state. Then you can create and return a viable Pet object from your creational method.
Also, your code has lots of compilation errors, suggesting that you could improve the way that you create your code. Never try to add new code to "bad" code, to code that won't compile. If possible, use an IDE such as NetBeans, Eclipse, or IntelliJ to help you create your programs. The IDE's will flag you if any of your code contains compilation errors, and then the key is: don't add new code until you've first fixed the existing compilation error. If you can't use an IDE, then you must compile early and often, and do the same thing -- fix all errors before adding new.
First, I would recommend shooting through a tutorial first before attempting this, do all the hello worlds covering scope, objects, arrays and functions. Get familiar with Object Oriented Style, although thats not even procedural programming ... nothing returns 2 objects ... always 1 (it could be an array containing many objects, but an array is a single object)
Moving on,although this is terrible coding practice, but its ok for a beginner,since your functions are all static, create a private static variable inside each function and create getter functions
//convert
String petname = scanner.nextLine();
// To this
private static String petname = scanner.nextLine();
// Then add this below it
public static String getPetName()
{
return petname;
}
and same for every piece of data you need.
Now remove the return statement from all of your functions and declare return type as void
Then call all functions from Main,
askpetname();
thirstlevel();
then print final output (after you have called the functions) as such
System.out.println("Petname: " + getPetname + " ThirstLevel: " + getThirstLevel() + " HungerLevel: " + getHungerLevel);
this is what i have so far and what im trying to do i dont know how to access both parts of the split this code is really wrong but i dont know how to do what i want(yes it is for school)
public class Relatives
{
private Map<String,Set<String>> map;
/**
* Constructs a relatives object with an empty map
*/
public Relatives()
{
map = new TreeMap<String,Set<String>>();
}
/**
* adds a relationship to the map by either adding a relative to the
* set of an existing key, or creating a new key within the map
* #param line a string containing the key person and their relative
*/
public void setPersonRelative(String line)
{
String[] personRelative = line.split(" ");
if(map.containsKey(personRelative[0]))
{
map.put(personRelative[0],map.get(personRelative[1])+personRelative[1]);
}
else
{
map.put(personRelative[0],personRelative[1]);
}
}
im trying to access the person and add to there current relatives and if the dont exist create a new person with that relative
how would i format it so it returns like this
Dot is related to Chuck Fred Jason Tom
Elton is related to Linh
i have this but get error
public String getRelatives(String person)
{
return map.keySet();
}
You cannot add an item to a Set using the += operator; you must use the add method.
Also, you have to create the set the first time you are going to use it.
The fixed code could look like:
String[] personRelative = line.split(" ");
String person = personRelative[0];
String relative = personRelative[1];
if(map.containsKey(person))
{
map.get(person).add(relative);
}
else
{
Set<String> relatives = new HashSet<String>();
relatives.add(relative);
map.put(person,relatives);
}
Hey all. I've been asked to create a method that uses an iterator to print details of 'lots'. I'm able to create an iterator that prints all of the details, however, for any lots that haven't been bought, a message should print out this fact and I'm unsure how I can add that code in. It is the public void close method I'm focusing on. This is what I have so far. Help is greatly appreciated.
public class Auction{
// The list of Lots in this auction.
private final ArrayList<Lot> lots;
// The number that will be given to the next lot entered
// into this auction.
private int nextLotNumber;
/**
* Create a new auction.
*/
public Auction(){
lots = new ArrayList<Lot>();
nextLotNumber = 1;
}
/**
* Enter a new lot into the auction.
*
* #param description
* A description of the lot.
*/
public void enterLot(final String description){
lots.add(new Lot(nextLotNumber, description));
nextLotNumber++;
}
/**
* Show the full list of lots in this auction.
*/
public void showLots(){
for(final Lot lot : lots){
System.out.println(lot.toString());
}
}
public void close(){
final Iterator<Lot> it = lots.iterator();
while(it.hasNext()){
}
}
/**
* Bid for a lot. A message indicating whether the bid is
* successful or not is printed.
*
* #param number
* The lot number being bid for.
* #param bidder
* The person bidding for the lot.
* #param value
* The value of the bid.
*/
public void bidFor(final int lotNumber,
final Person bidder,
final long value){
final Lot selectedLot = getLot(lotNumber);
if(selectedLot != null){
final boolean successful =
selectedLot.bidFor(new Bid(bidder, value));
if(successful){
System.out.println("The bid for lot number " + lotNumber
+ " was successful.");
} else{
// Report which bid is higher.
final Bid highestBid = selectedLot.getHighestBid();
System.out.println("Lot number: " + lotNumber
+ " already has a bid of: " + highestBid.getValue());
}
}
}
}
Does the Lot class have a flag indicating if it's purchased or not? If so then
for(final Lot lot : lots){
if (!lot.purchased) {
System.out.println("not bought");
}
}
BTW - I noticed you're using the pre for-each style iterator in the close method. There's no reason to do this since you'll have access to individual Lot instances in the for-each also.
I would add the information you want the Lot to print to the Lot.toString() I would suggest your close() method should close() each lot, and the lot should print anything which needs to be printed.
Add an attribute to the Lot class of type Person called "winner" or something similar.
In the bidFor method, in the if (successful) block, set the winner attribute:
selectedLot.setWinner(bidder);
Then when iterating through the lots, if the winner attribute is null, print your message that the lot hasn't been bought.
Or you could use:
if (lot.getHighestBid() == null)
depending on how the Lot class is implemented, hard to know without seeing the Lot class.