i need to count total doctor transaction using an attribute id, and then total amount payment doctor using an attribute id from list.
how to resolve it? i'm stuck to count it.
please to tell
this is my code:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class SandboxList {
public static void main(String[] args) {
List<Doctor> doctors = new ArrayList<Doctor>();
doctors.add(new Doctor("1726", "John", 10000.00));
doctors.add(new Doctor("4321", "Max", 20000.00));
doctors.add(new Doctor("1726", "John", 40000.00));
doctors.add(new Doctor("4321", "Max", 2000.00));
doctors.add(new Doctor("7765", "Sam", 50000.00));
doctors.add(new Doctor("4321", "Max", 6000.00));
/* I want Output should be Like below
ID : 1726 Name : John Total_payment : 50000.00 total_transaction : 2
ID : 4321 Name : Max Total_payment : 28000.00 total_transaction : 3
ID : 7765 Name : Sam Total_payment : 50000.00 total_transaction : 1
*/
Map<String, List<Doctor>> groupedDoctors = new HashMap<String, List<Doctor>>();
for (Doctor doctor: doctors) {
String key = doctor.doctor_id;
if (groupedDoctors.get(key) == null) {
groupedDoctors.put(key, new ArrayList<Doctor>());
}
groupedDoctors.get(key).add(doctor);
}
Set<String> groupedDoctorsKeySet = groupedDoctors.keySet();
for (String doctorId: groupedDoctorsKeySet) {
List<Doctor> dctrs = groupedDoctors.get(doctorId);
for (Doctor doctor : dctrs) {
System.out.println("ID : "+doctor.doctor_id+"\t"+"Name : "+doctor.doctor_name+"\t"+"total_Payment : "+doctor.doctor_payment);
}
}
}
}
class Doctor {
String doctor_id;
String doctor_name;
Double doctor_payment;
Doctor(String doctor_id, String doctor_name, Double doctor_payment) {
this.doctor_id = doctor_id;
this.doctor_name = doctor_name;
this.doctor_payment = doctor_payment;
}
}
Change the code for:
for (String doctorId : groupedDoctorsKeySet) {
List<Doctor> dctrs = groupedDoctors.get(doctorId);
Double total_payment = 0d;
String doctor_name = null;
for (Doctor doctor : dctrs) {
if (doctor_name == null) {
doctor_name = doctor.doctor_name;
}
total_payment += doctor.doctor_payment;
}
Doctor doctor = new Doctor(doctorId, doctor_name, total_payment);
System.out.println("ID : " + doctor.doctor_id + "\t" + "Name : " + doctor.doctor_name + "\ttotal_Payment : " + doctor.doctor_payment);
}
You could do something like this after you group the doctors:
Set<String> groupedDoctorsKeySet = groupedDoctors.keySet();
for (String doctorId : groupedDoctorsKeySet)
{
List<Doctor> dctrs = groupedDoctors.get(doctorId);
if (dctrs != null && dctrs.size() > 0)
{
StringBuilder sb = new StringBuilder();
sb.append("ID : ").append(doctorId).append("\t").append("Name : ");
sb.append(dctrs.get(0).doctor_name).append("\t").append("total_Payment : ");
double total = 0;
// sum the payment
for (Doctor d : dctrs)
{
total += d.doctor_payment;
}
sb.append(total).append("\t").append("total_transaction : ");
sb.append(dctrs.size());
System.out.println(sb);
}
}
Outputs:
ID : 4321 Name : Max total_Payment : 28000.0 total_transaction : 3
ID : 7765 Name : Sam total_Payment : 50000.0 total_transaction : 1
ID : 1726 Name : John total_Payment : 50000.0 total_transaction : 2
I have used only 2 data structure so that resources can be consume as less as much possible.
class Doctor {
String doctor_id;
String doctor_name;
Double doctor_payment;
Doctor(String doctor_id, String doctor_name, Double doctor_payment) {
this.doctor_id = doctor_id;
this.doctor_name = doctor_name;
this.doctor_payment = doctor_payment;
}
public String getDoctor_id() {
return doctor_id;
}
public String getDoctor_name() {
return doctor_name;
}
public Double getDoctor_payment() {
return doctor_payment;
}
public void setDoctor_id(String doctor_id) {
this.doctor_id = doctor_id;
}
public void setDoctor_name(String doctor_name) {
this.doctor_name = doctor_name;
}
public void setDoctor_payment(Double doctor_payment) {
this.doctor_payment = doctor_payment;
}
/*
HashCode() and equal() method is override because I want to identify the
element in collection on basis of ID's
*/
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Doctor other = (Doctor) obj;
if (doctor_id == null) {
if (other.doctor_id != null)
return false;
} else if (!doctor_id.equals(other.doctor_id))
return false;
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((doctor_id == null) ? 0 :
doctor_id.hashCode());
return result;
}
}
public class SandboxList {
public static void main(String[] args) {
List<Doctor> doctors = new ArrayList<Doctor>();
doctors.add(new Doctor("1726", "John", 10000.00));
doctors.add(new Doctor("4321", "Max", 20000.00));
doctors.add(new Doctor("1726", "John", 40000.00));
doctors.add(new Doctor("4321", "Max", 2000.00));
doctors.add(new Doctor("7765", "Sam", 50000.00));
doctors.add(new Doctor("4321", "Max", 6000.00));
Vector<Doctor> groupedDoctors = new Vector<Doctor>();
Doctor loopVariable;
int index;
for (Doctor doctor : doctors) {
index = groupedDoctors.indexOf(doctor);
// -1 shows groupedDoctors doesn't contain of this doctor
if (-1!=index) {
loopVariable = groupedDoctors.elementAt(index);
groupedDoctors.removeElementAt(index);
loopVariable.setDoctor_payment(doctor.getDoctor_payment() + loopVariable.getDoctor_payment());
groupedDoctors.add(loopVariable);
}
else{
groupedDoctors.addElement(doctor);
}
}
for (Doctor doctor : groupedDoctors) {
System.out.println("ID : " + doctor.doctor_id + "\t" + "Name : " +
doctor.doctor_name + "\t"
+ "total_Payment : " + doctor.doctor_payment);
}
}
}
You may need the code like this:
Set<String> groupedDoctorsKeySet = groupedDoctors.keySet();
if (groupedDoctorsKeySet != null) {
ArrayList<String> list = new ArrayList(groupedDoctorsKeySet);
Collections.sort(list, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
if (Long.valueOf(o1) < Long.valueOf(o2)) return -1;
else if (Long.valueOf(01) == Long.valueOf(02)) return 0;
else return 1;
}
});
for (String doctorId: list) {
List<Doctor> dctrs = groupedDoctors.get(doctorId);
if (dctrs != null) {
double sum = 0;
String name = null;
for (Doctor doctor : dctrs) {
if (name == null) name = doctor.doctor_name;
sum += doctor.doctor_payment;
}
System.out.println(String.format("ID : %s\tName : %s\tTotal_payment : %.2f total_transaction : %d", new Object[]{doctorId, name, sum, dctrs.size()}));
}
}
}
and the output is:
ID : 1726 Name : John Total_payment : 50000.00 total_transaction : 2
ID : 4321 Name : Max Total_payment : 28000.00 total_transaction : 3
ID : 7765 Name : Sam Total_payment : 50000.00 total_transaction : 1
Using what you already have you could update the grouped section to the below:
Set<String> groupedDoctorsKeySet = groupedDoctors.keySet();
for (String doctorId: groupedDoctorsKeySet) {
List<Doctor> dctrs = groupedDoctors.get(doctorId);
if (dctrs.size() <= 0) { continue; }
Doctor doctor = dctrs.get(0); //These should all be the same doctor due to the key
double totalPayment = 0.0;
for(Doctor doc : dctrs){ totalPayment += doc.doctor_payment; }
System.out.println("ID : " + doctor.doctor_id + "\tName : " + doctor.doctor_name
+ "\ttotal_Payment : " + totalPayment + "\tNumber Of transactions: " + dctrs.size());
}
=========================================================================
Alternative Solution
Alternatively, if the purpose of duplicating the doctors was to be able to examine each payment individually at some point in the future, you could have single Doctor's but with lists of payments. Exposing a method to update the doctor with new payment details
You would then be able to get the number of transactions from the size of that list and the Doctor object would be able to determine the total itself:
class Doctor {
String doctor_id;
String doctor_name;
List<Double> doctor_payments = new ArrayList<>();
Doctor(String doctor_id, String doctor_name, Double doctor_payment) {
this.doctor_id = doctor_id;
this.doctor_name = doctor_name;
this.doctor_payments.add(doctor_payment);
}
public void processPayment(double paymentAmount){
this.doctor_payments.add(paymentAmount);
}
#Override
public String toString(){
double totalPayment = 0.0;
for(Double payment : doctor_payments){ totalPayment += payment; }
return "ID : " + doctor_id + "\tName : " + doctor_name
+ "\ttotal_Payment : " + totalPayment + "\tNumber Of transactions: " + doctor_payments.size();
}
}
Example usage:
Doctor john = new Doctor("1726", "John", 10000.00);
john.processPayment(40000.00);
System.out.println(john);
Output: ID : 1726 Name : John total_Payment : 50000.0 Number Of transactions: 2
Related
I am a student who has just started getting touched with coding. I was trying to code a cashback calculation, but I got the wrong output. The calculation is based on which category user chooses; petrol, groceries, ewallet, etc. Once I get the categories, the list will get the amount based on the categories and calculate with the bonus cash back and cash back on eligible spend. If the amount calculated is more than or equal to 15, it will return 15.
The cashback calculation code:
private void function1() {
double amountGet, cashback = 0;
for (int i = 0; i< dataList.size(); i++) {
if(dataList.get(i).getCategory() == "Petrol Spend") {
amountGet = dataList.get(i).getAmount();
cashback = amountGet * 0.08;
if(cashback > 15) {
cashback = 15.00;
}
} else if(dataList.get(i).getCategory() == "Groceries Spend") {
amountGet = dataList.get(i).getAmount();
cashback = (amountGet * 0.078) + (amountGet * 0.002);
if(cashback > 15) {
cashback = 15.00;
}
} else if(dataList.get(i).getCategory() == "eWallet Transaction") {
amountGet = dataList.get(i).getAmount();
cashback = (amountGet * 0.078) + (amountGet*0.002);
if(cashback > 15) {
cashback = 15.00;
}
} else if (dataList.get(i).getCategory() == "Other Eligible Spend") {
amountGet = dataList.get(i).getAmount();
cashback = amountGet * 0.002;
if (cashback > 15) {
cashback = 15.00;
}
}
list.add(cashback);
}
}
This button for invoking the calculation code:
calculateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
calculateCashBack();
}
});
private void calculateCashBack() {
if (totalAmount >=2000) {
function1();
} else {
function2();
}
for (int i =0; i< list.size(); i++) {
Log.d(TAG, "Item with ID :" + dataList.get(i).getId() + "with the amount of : RM" + dataList.get(i).getAmount() + "get Cashback of : RM" + list.get(i));
}
}
This is my output:
I would very much appreciate any the help from the experts...
As #GhostCat said, you should use String.equals() to compare strings. Here is an example of a more optimize, and prettier, code
// Init static values here
private Map<String, Float> cashbacks; // HashMap linking Category to dedicated cashback
static {
cashbacks = new HashMap<>();
cashbacks.put("Petrol Spend", 0.08f);
cashbacks.put("Groceries Spend", 0.08f);
cashbacks.put("eWallet Transaction", 0.08f);
cashbacks.put("Other Eligible Spend", 0.002f);
}
/**
* Compute cashbacks for a list of data
* #param dataList List of data
* #return List of corresponding cashbacks
*/
private List<Float> function1(List<Data> dataList) {
List<Float> results = new ArrayList<>();
for (Data data : dataList) {
// Find the category in the map
Float cash = cashbacks.get(data.category());
if (cash == null) {
cash = 0f; // default value here if no category found
}
// compute the total amount and limit the result to 15
results.add(Math.min(data.getAmount() * cash, 15));
}
return results;
}
How to use it? Simple:
private void calculateCashBack() {
List<Float> cashbacks;
if (totalAmount >=2000) {
cashbacks = function1(dataList);
} else {
cashbacks = function2(dataList); // I suppose that this function has the same signature
}
for (int i =0; i< cashbacks.size(); i++) {
Log.d(TAG, "Item with ID :" + dataList.get(i).getId() + " with the amount of : RM " + dataList.get(i).getAmount() + " get Cashback of : RM " + cashbacks.get(i));
}
}
So, I'm trying to figure out how to get values of an array list from another class and print certain values depending on user input.
For example, firstly a user is asked to provide a location, once they enter a location, it has to read the user input and output the results according to the location.an image is provided about the output.
For some reason it doesn't output the correct values from array list.
Could you please help me out?
This is my code for reading values from array list.
public class Program {
ArrayList<Properties> property = Properties.getMelbnbProperty();
int i = 1;
for(i = 1; i < (property.size());) {
System.out.println(property.get(i));
break;
}
ArrayList<Properties> output = Properties.getMelbnbProperty();
if(Properties.getMelbnbProperty().contains(choice)) {
output.addAll(Properties.getMelbnbProperty());
}
} }
This is my code for array list.
public class Properties {
public static ArrayList<Properties> getMelbnbProperty() {
// Below is an arraylist where I have stored the Melbnb data
ArrayList<Properties> property = new ArrayList<Properties>();
property.add(new Properties("Private room in the heart of Southbank"));
property.add(new Properties("Spacious bedroom in a cosy apartment in South Yarra\n"));
property.add(new Properties("Ensuite room with great views"));
property.add(new Properties("Single room next to Carlton Gardens"));
property.add(new Properties("Studio close to Melbourne CBD"));
property.add(new Properties("1-bedroom CBD view suite near Melbourne Central and RMIT"));
property.add(new Properties("Stylish two bedroom in CBD"));
property.add(new Properties("Sky high studio with amazing views"));
property.add(new Properties("Budget accommodation bunk beds"));
property.add(new Properties("A beautiful room near Marvel Stadium"));
return property;
}}
The code you have provided in your question post is incomplete and in a way doesn't make sense to what your image displays. I do however understand what you are trying to accomplish but the way I see it your properties class is somewhat under-nourished.
I don't know if this is the intentional purpose but your for loop:
int i = 1;
for(i = 1; i < (property.size());) {
System.out.println(property.get(i));
break;
}
is designed to pull out 1 object from the property ArrayList. This loop is completely unnecessary since just supplying an index value of 1 to the ArrayList#get() method does exactly the same thing and is only a single line of code, for example:
System.out.println(property.get(1));
I say this because your for loop initializer starts at index 1, there is no iterator for the loop, and you apply the break statement directly after the display of the object within the ArrayList.
To access all elements within the ArrayList (your post indicates) you would need to do something like this:
for (int i = 0; i < properties.size(); i++) {
System.out.println(properties.get(i));
}
Or you can use:
for (String props: properties) {
System.out.println(props);
}
To be honest, what you are showing for code in grossly underdeveloped. I don't want to come across as insulting but it's obvious that you are not showing as much as you should be and therefore it is extremely difficult to provide you with any concrete solution to your problem. For this reason, I think it is just easier to provide you with a working demo console application which would allow you to perhaps grasp some concepts from.
The runnable code below consists of two specific classes, the start up class named SimpleBNBDemo which contains the main() method and the Properties class which allows you to instantiate instances of different BNB properties. As you can see, the Properties class is somewhat more fulfilled than the class you provided in your question post. Take the time to read through the code and try to follow its flow. Do keep in mind, although runnable this is only a Demo application and is in now way a complete works. I personally would never hard-code fill an ArrayList with Object data. This data should come from and or saved to a file system or database. However, for demo purposes this will suffice.
The SimpleBNBDemo class:
public class SimpleBNBDemo {
// Field variables
public final static String LS = System.lineSeparator();
public final static java.util.Scanner USER_INPUT = new java.util.Scanner(System.in);
// class member variable
private Properties prop = new Properties();
private final String line = "------------------------------------------------";
private int pwAttempts = 0;
public static void main(String[] args) {
// Started this way to avoid the need for statics
new SimpleBNBDemo().startApp(args);
}
private void startApp(String[] args) {
/* Create Properties instances...
You can do this with whatever means you like. */
java.util.List<Properties> properties = prop.getProperties();
properties.add(new Properties("Southbank Mannor", "Room", "Private room in the heart of Southbank.", "South", 86.00d, true));
properties.add(new Properties("Yarra House", "Room", "Spacious bedroom in a cosy apartment in South Yarra.", "South", 74.00d, true));
properties.add(new Properties("Ensuite Haven", "Room", "Ensuite room with great views.", "West", 65.50d, true));
properties.add(new Properties("Carlton Place", "Room", "Single room next to Carlton Gardens.", "South", 78.00d, true));
properties.add(new Properties("Melbourne Studio", "Studio", "Studio close to Melbourne CBD.", "East", 78.00d, true));
properties.add(new Properties("Melbourne Delight", "Room", "1-bedroom CBD view suite near Melbourne Central and RMIT.", "North", 135.00d, true));
properties.add(new Properties("CBD House", "Suit", "Stylish two bedroom in CBD.", "West", 100.00d, true));
properties.add(new Properties("Sky-High", "Studio", "Sky high studio with amazing views.", "North", 95.00d, true));
properties.add(new Properties("Budgeteer", "Room", "Budget accommodation bunk beds.", "South", 65.00d, true));
properties.add(new Properties("Stadium House", "Room", "A beautiful room near Marvel Stadium.", "East", 95.00d, true));
println("Welcome to MelBNB" + LS + line);
println();
// Menu 1 - Main Menu
String choice = "";
String[] locations = prop.getAllLocations();
if (locations.length == 0) {
printErr("No BNB's with Location in database yet!");
return;
}
while (choice.isEmpty()) {
println("Select from Main Menu:");
println(" 1) List all Accomodations");
println(" 2) Search by location");
println(" 3) Browse by type of accomodation");
println(" 4) Filter by rating");
println(" 5) Rate an accomodation");
println(" 6) Exit (quit)");
print("Please choose: -> ");
choice = USER_INPUT.nextLine().trim();
// Validate Entry...switch/case works great for input validation.
switch (choice) {
case "1":
listAllAccomodations();
break;
case "2":
searchByLocation();
break;
case "3":
searchByAccomodationType();
break;
case "4":
searchByRating();
break;
case "5":
rateAnAccomodation();
break;
case "6":
break;
case "~admin~":
adminMenu();
break;
case "~admin attempts reset~":
pwAttempts = 0;
println();
break;
default:
println("Invalid Entry (" + choice + ")! Try again..." + LS);
}
// Was 'Exit' (4) selected?
if (choice.equals("6")) {
// Break out of loop to end application.
println(LS + "Thank you for visiting MelBNB, Bye-Bye." + LS);
break;
}
choice = ""; // Reset 'choice' to be empty in order to loop again..
}
}
private void adminMenu() {
String pwrd = "";
while (pwrd.isEmpty()) {
if (pwAttempts >= 3) {
println(LS + "Admin Menu is NOT Available!" + LS + "To many failed "
+ "consecutive password attempts!" + LS + "Only " + pwAttempts
+ " consecutive attempts are allowed." + LS);
return;
}
print(LS + "Please enter Admin Password (c to cancel): --> ");
pwrd = USER_INPUT.nextLine().trim();
if (pwrd.equalsIgnoreCase("c")) {
println();
return;
}
int psum = 0;
for (int i = 0; i < pwrd.length(); i++) {
psum += pwrd.charAt(i);
}
if (psum != 624) {
pwAttempts++;
println("Invalid Password! Try again...");
pwrd = "";
}
}
pwAttempts = 0;
println();
println("***********************************************");
println("*** Administrative options would go here! ***");
println("*** Press Enter To Continue ***");
println("***********************************************");
String nothing = USER_INPUT.nextLine().trim();
}
private void listAllAccomodations() {
println(LS + "All Available Accomodations:");
println("----------------------------");
int cntr = 0;
String underline = "";
for (Properties pp : prop.getProperties()) {
cntr++;
String str = pp.toStringTable(pp, cntr == 1);
underline = String.join("", java.util.Collections.nCopies(str.length(), "="));
println(str);
if (cntr == 15) {
println("<- Press Enter To Continue ->");
String nuthin = USER_INPUT.nextLine().trim();
cntr = 0;
}
}
println(underline + LS);
}
private void searchByLocation() {
String[] locationTypes = prop.getAllLocations();
java.util.Arrays.sort(locationTypes);
String locationChoice = "";
while (locationChoice.isEmpty()) {
println();
println("Select the desired location:");
int i = 0;
for ( ; i < locationTypes.length; i++) {
println(" " + (i + 1) + ") " + locationTypes[i]);
}
println(" " + (i + 1) + ") Cancel");
print("Please choose: -> ");
locationChoice = USER_INPUT.nextLine().trim();
// Validate Entry...
if (!locationChoice.matches("[1-" + (locationTypes.length + 1) + "]")) {
println("Invalid Entry (" + locationChoice + ")! Try again..." + LS);
locationChoice = "";
}
}
if (locationChoice.equals(String.valueOf(locationTypes.length + 1))) {
println();
return;
}
String location = locationTypes[Integer.valueOf(locationChoice)-1];
java.util.List<Properties> p = prop.getPropertiesByLocation(location);
if (p.isEmpty()) {
println("No accomodations available in the " + location + " area!" + LS);
return;
}
String str = "Available accomodation within the " + location + " area:";
println(LS + str);
println(String.join("", java.util.Collections.nCopies(str.length(), "-")));
int cntr = 0;
for (Properties pp : p) {
cntr++;
println(pp.toStringTable(pp, cntr == 1));
}
println(line + LS);
}
private void searchByAccomodationType() {
String[] accTypes = prop.getAllAccomodationTypes();
java.util.Arrays.sort(accTypes);
String accChoice = "";
while (accChoice.isEmpty()) {
println();
println("Select the desired accomodation type:");
int i = 0;
for ( ; i < accTypes.length; i++) {
println(" " + (i + 1) + ") " + accTypes[i]);
}
println(" " + (i + 1) + ") Cancel");
print("Please choose: -> ");
accChoice = USER_INPUT.nextLine().trim();
// Validate Entry...
if (!accChoice.matches("[1-" + (accTypes.length + 1) + "]")) {
println("Invalid Entry (" + accChoice + ")! Try again..." + LS);
accChoice = "";
}
}
if (accChoice.equals(String.valueOf(accTypes.length + 1))) {
println();
return;
}
String acc = accTypes[Integer.valueOf(accChoice)-1];
java.util.List<Properties> p = prop.getPropertiesByAccomodationType(acc);
if (p.isEmpty()) {
println("No accomodation type of " + acc + " is available!" + LS);
return;
}
String str = "Available accomodation that are of type '" + acc + "':";
println(LS + str);
println(String.join("", java.util.Collections.nCopies(str.length(), "-")));
int cntr = 0;
for (Properties pp : p) {
cntr++;
println(pp.toStringTable(pp, cntr == 1));
}
println(line + LS);
}
private void searchByRating() {
String rateChoice = "";
while (rateChoice.isEmpty()) {
println();
println("Enter the desired accomodation rating (1 to 5);");
print( "Enter c to cancel. Desired Rating: --> ");
rateChoice = USER_INPUT.nextLine().trim();
if (rateChoice.equalsIgnoreCase("c")) {
return;
}
// Validate Entry...
if (!rateChoice.matches("[1-5]")) {
println("Invalid Entry (" + rateChoice + ")! Try again..." + LS);
rateChoice = "";
}
}
int rating = Integer.valueOf(rateChoice);
java.util.List<Properties> p = prop.getPropertiesByRating(rating);
if (p.isEmpty()) {
println("No accomodation available with the rating of " + rating + "!" + LS);
return;
}
String str = "Available accomodation with a rating of '" + rating + "':";
println(LS + str);
println(String.join("", java.util.Collections.nCopies(str.length(), "-")));
int cntr = 0;
for (Properties pp : p) {
cntr++;
println(pp.toStringTable(pp, cntr == 1));
}
println(line + LS);
}
private void rateAnAccomodation() {
/* Displayed ratings are always the AVERAGE of all ratings
provided for that particular propety. This is done within
the 'Properties.addRating()' method. For this reason and
for other obvious reasons the Properties List should be
saved to either a file or a database. If this is not done
then all added or modified data will be lost when the
application closes. The Properties List data should NOT
be hard-coded. It should be loaded in when the application
starts and saved to storage when data is added or modified.
*/
String[] pNames = prop.getAllPropertyNames();
String nameToRate = "";
while (nameToRate.isEmpty()) {
println(LS + "Enter the name of the accomodation you want to rate:");
print( "Enter 'c' to cancel. Rating: --> ");
nameToRate = USER_INPUT.nextLine().trim();
if (nameToRate.equalsIgnoreCase("c")) {
return;
}
// Validate Entry............................
if (nameToRate.isEmpty()) {
println("Invalid Entry! You must enter a Name! Try again...");
nameToRate = "";
continue;
}
// Does the name exist in List?
boolean found = false;
for (String name : pNames) {
if (name.equalsIgnoreCase(nameToRate)) {
// Yes it does...
found = true;
break; // Break out of this loop.
}
}
if (!found) {
println("Invalid Entry (" + nameToRate + ")!" + LS
+ "Can not find the name supplied! Try again..." + LS);
nameToRate = "";
}
}
//.................................................
/* If we get to here then the name supplied
(regarless of letter case) is in the List. */
String rateNum = "";
while (rateNum.isEmpty()) {
println();
print("Enter your rating (1 to 5 or 'c' to cancel): --> ");
rateNum = USER_INPUT.nextLine().trim();
if (rateNum.equalsIgnoreCase("c")) {
return;
}
// Validate Entry...
if (!rateNum.matches("[1-5]")) {
println("Invalid Entry (" + rateNum + ")! Try again..." + LS);
rateNum = "";
}
println();
}
// Set the rating.
int rating = Integer.valueOf(rateNum);
for (Properties p : prop.getProperties()) {
if (p.getPropertyName().equalsIgnoreCase(nameToRate)) {
int avgRating = p.getAverageRating();
p.addRating(rating);
println("Your rating of " + rating + " has been added to the accomodation" + LS
+ "named '" + nameToRate + "' which has moved its overall rating" + LS
+ "average from " + avgRating + " to an overall average rating of " +
p.getAverageRating() + "." + LS + "This is based on " +
p.getTotalNumberOfRatingsDone() + " rating(s) on the accomodation." + LS);
}
}
}
public static void println(Object... obj) {
if (obj.length > 0) {
System.out.println(obj[0]);
}
else {
System.out.println();
}
}
public static void printErr(Object... obj) {
if (obj.length > 0) {
System.err.println(obj[0]);
}
else {
System.err.println();
}
}
public static void print(Object... obj) {
if (obj.length > 0) {
System.out.print(obj[0]);
}
else {
System.out.print("");
}
}
}
The Properties class:
public class Properties {
public static java.util.List<Properties> properties = new java.util.ArrayList<>();
private String propertyName;
private String accomodationType;
private String description;
private String location;
private double pricePerDay;
private int averageRating = 0;
private int totalNumberOfRatings;
private boolean available;
// Constructor #1
public Properties() { }
// Constructor #2
public Properties(String propertyName, String accomodationType, String description,
String location, double pricePerDay, boolean available) {
this.propertyName = propertyName;
this.accomodationType = accomodationType;
this.description = description;
this.location = location;
this.pricePerDay = pricePerDay;
this.available = available;
}
// Getters & Setters
public java.util.List<Properties> getProperties() {
return properties;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public String getAccomodationType() {
return accomodationType;
}
public void setAccomodationType(String accomodationType) {
this.accomodationType = accomodationType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public double getPricePerDay() {
return pricePerDay;
}
public void setPricePerDay(double pricePerDay) {
this.pricePerDay = pricePerDay;
}
public int getAverageRating() {
return this.averageRating;
}
public void addRating(int rating) {
// Rateing is an integer value from 1 to 5.
// Where 1 is Bad and 5 Excellent.
if (rating < 1) { rating = 1; }
else if (rating > 5) { rating = 5; }
int sum = 0, r = 0;
for (Properties p : properties) {
if (p.propertyName.equalsIgnoreCase(this.propertyName)) {
r++;
sum += rating;
}
}
if (sum > 0 && r > 0) {
this.averageRating = sum / r;
}
else {
this.averageRating = rating;
}
this.totalNumberOfRatings++;
}
public boolean isAvailable() {
return available;
}
public void setAvailable(boolean available) {
this.available = available;
}
#Override
public String toString() {
return propertyName + ", " + accomodationType + ", " + description + ", "
+ location + ", " + pricePerDay + ", " + averageRating + ", "
+ available;
}
public String toStringTable(Properties p, boolean... addHeader) {
boolean applyHeader = false;
if (addHeader.length > 0) {
applyHeader = addHeader[0];
}
String symbol = java.util.Currency.getInstance(java.util.Locale.getDefault()).getSymbol();
String header = "", underline = "", ls = System.lineSeparator();
StringBuilder sb = new StringBuilder("");
header = String.format("%-18s %-10s %-50s %-10s %-10s %-8s %-6s%n", "BNB Name",
"BNB Type", "BNB Description", "Location", "Price/Day", "Rating", "Avail.");
underline = String.join("", java.util.Collections.nCopies(header.length(), "=")) + ls;
if (applyHeader) {
sb.append(header).append(underline);
}
String[] desc = p.description.split("\\s+");
java.util.List<String> descTmp = new java.util.ArrayList<>();
StringBuilder sb2 = new StringBuilder("");
for (String str : desc) {
if ((sb2.toString() + " " + str).length() > 50) {
descTmp.add(sb2.toString());
sb2.setLength(0);
}
if (!sb2.toString().isEmpty()) {
sb2.append(" ");
}
sb2.append(str);
}
if (!sb2.toString().isEmpty()) {
descTmp.add(sb2.toString());
}
sb.append(String.format("%-18s %-10s %-50s %-12s " + symbol + "%-10.2f %-7s %-6s",
p.propertyName, p.accomodationType, descTmp.get(0), p.location,
p.pricePerDay, p.averageRating, (p.available ? "Yes" : "No")));
if (descTmp.size() > 1) {
for (int i = 1; i < descTmp.size(); i++) {
sb.append(ls).append(String.format("%-18s %-10s %-50s %-12s %-10s %-7s %-6s",
" "," ", descTmp.get(i), " ", " ", " ", " "));
}
}
return sb.toString();
}
public String[] getAllPropertyNames() {
java.util.List<String> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure names retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.propertyName)) {
tmp.add(prop.propertyName);
}
}
return tmp.toArray(new String[tmp.size()]);
}
public String[] getAllAccomodationTypes() {
java.util.List<String> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure accomodations retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.accomodationType)) {
tmp.add(prop.accomodationType);
}
}
return tmp.toArray(new String[tmp.size()]);
}
public java.util.List<Properties> getPropertiesByLocation(String location) {
java.util.List<Properties> tmp = new java.util.ArrayList<>();
for (Properties p : Properties.properties) {
if (p.location.equalsIgnoreCase(location) && !tmp.contains(p)) {
tmp.add(p);
}
}
return tmp;
}
public java.util.List<Properties> getPropertiesByAccomodationType(String accomodationType) {
java.util.List<Properties> tmp = new java.util.ArrayList<>();
for (Properties p : Properties.properties) {
if (p.accomodationType.equalsIgnoreCase(accomodationType) && !tmp.contains(p)) {
tmp.add(p);
}
}
return tmp;
}
public java.util.List<Properties> getPropertiesByRating(int rating) {
java.util.List<Properties> tmp = new java.util.ArrayList<>();
for (Properties p : Properties.properties) {
if (p.averageRating == rating && !tmp.contains(p)) {
tmp.add(p);
}
}
return tmp;
}
public int getTotalNumberOfRatingsDone() {
return this.totalNumberOfRatings;
}
public String[] getAllDescriptions() {
java.util.List<String> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure descriptions retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.description)) {
tmp.add(prop.description);
}
}
return tmp.toArray(new String[tmp.size()]);
}
public String[] getAllLocations() {
java.util.List<String> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure locations retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.location)) {
tmp.add(prop.location);
}
}
return tmp.toArray(new String[tmp.size()]);
}
public double[] getAllPerDayPrices() {
java.util.List<Double> tmp = new java.util.ArrayList<>();
for (Properties prop : properties) {
// Make sure locations retrieved are Unique (DISTINCT)
if (!tmp.contains(prop.pricePerDay)) {
tmp.add(prop.pricePerDay);
}
}
// Convert List<Double> to double[]...
double[] prices = new double[tmp.size()];
for (int i = 0; i < tmp.size(); i++) {
prices[i] = tmp.get(i);
}
return prices;
}
}
I have a lot of JSON files in the following format. I want to map one attribute named Timings to integer.
test.json
"Rating": {
"ratingValue": "4.636365",
"bestRating": "5",
"worstRating": "1",
"ratingCount": "66"
},
"Timings": {
"cookTime": "PT1H",
"prepTime": "PT10M",
"totalTime": "PT1H10M"
}
I want to store the output in another JSON file after mapping. Let say, totalTime in Timings is 1H10M then we assign this as "totalTime:7". If its, "30M" we can assign this as "totalTime:3". I want to do this using java.
Required output
"Rating":
{
"ratingValue": "4.636365",
},
"Timings":
{
"totalTime": "7"
}
I tried this :
class Timings {
private String cookTime;
private String prepTime;
private String totalTime;
public String getCookTime() {
return cookTime;
}
public void setCookTime(String cookTime) {
this.cookTime = cookTime;
}
public String getPrepTime() {
return prepTime;
}
public void setPrepTime(String prepTime) {
this.prepTime = prepTime;
}
public String getTotalTime() {
return totalTime;
}
public void setTotalTime(String totalTime) {
this.totalTime = totalTime;
}
#Override
public String toString() {
return "Timings [cookTime=" + cookTime + ", prepTime=" + prepTime + ", totalTime=" + totalTime + "]";
}
}
public class Test {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Timings obj = mapper.readValue(new File("C:\\Users\\Anish\\Desktop\\abc.json"), Timings.class);
String totalTime = obj.getTotalTime().split("PT")[1];
int total = 0;
if (totalTime != null && !totalTime.isEmpty()) {
total = returnTotalTime(totalTime);
}
ObjectNode mainNode = mapper.createObjectNode();
ObjectNode timingNode = mapper.createObjectNode();
childNode.put("totalTime", (total > 9) ? (total / 10) : total);
mainNode.set("Timings", timingNode);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mainNode);
System.out.println(json);
}
private static int returnTotalTime(String totalTime) {
if (totalTime != null && !totalTime.isEmpty()) {
String[] timeValues = totalTime.split("H");
if (timeValues.length == 0) {
return 0;
} else if (timeValues.length < 2) {
if (timeValues[0].contains("M")) {
return (timeValues[0].split("M").length <= 0) ? 0
: timeValues[0].split("M")[0].isEmpty() ? 0 : Integer.parseInt(timeValues[0].split("M")[0]);
}
return timeValues[0].isEmpty() ? 0 : Integer.parseInt(timeValues[0]) * 60;
}
int hour = timeValues[0].isEmpty() ? 0 : Integer.parseInt(timeValues[0]) * 60;
int mins = (timeValues[1].split("M").length <= 0) ? 0
: timeValues[1].split("M")[0].isEmpty() ? 0 : Integer.parseInt(timeValues[1].split("M")[0]);
return (hour + mins);
}
return 0;
}
abc.json
{
"cookTime": "PT1H",
"prepTime": "PT10M",
"totalTime": "PT1H10M"
}
Output :
{
"Timings" : {
"totalTime" : "7"
}
}
When "totalTime": "PT30M", then :
Output :
{
"Timings" : {
"totalTime" : "3"
}
}
When "totalTime": "PT23M", then :
Output :
{
"Timings" : {
"totalTime" : "2"
}
}
You can use any library to parse Json data depending of your goals.
for example org.json is a good choice and here is an example:
JSONObject object = new JSONObject(stringData);
String time = object.getJSONObject("Timings").getString("cookTime");
this way you can parse every Json data and do your business after that.
Also you can use mapping your data to a class with gson or other tools.
I have a class which takes an arraylist of items determined by their name, price and quantity and is supposed to print each unique item and increase quantity accordingly if more than one of the same item are added to the arraylist.
I have 2 problems with my current code: Firstly, It only prints the last item in the arraylist. Secondly, it returns an incorrect quantity for the printed item.
package shop;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class ShoppingCart {
static ArrayList<Product> cart;
public ShoppingCart() {
ShoppingCart.cart = new ArrayList<Product>();
}
#Override
public String toString() {
DecimalFormat format = new DecimalFormat ("#.00");
int quantity = 0;
double price = 0;
String name = null;
double total = 0;
for (Product p: cart) {
quantity = p.getQuantity();
price = p.getPrice();
name = p.getName();
total = p.getTotalPrice();
}
return quantity + " * GBP " + format.format(price) + " " + name + " = GBP " + format.format(total);
}
public void add(Product p) {
if(cart.size() > 0) {
for (int i = 0; i < cart.size(); i++) {
if(cart.get(i).getName().equals(p.getName())
&& cart.get(i).getPrice() == p.getPrice()) {
cart.get(i).setQuantity(cart.get(i).getQuantity() + p.getQuantity());
}else {
cart.add(p);
}
}
}else {
cart.add(p);
}
}
public static void main(String[] args) {
ShoppingCart newCart = new ShoppingCart();
Product apple, apples, milk, caulk, ice, snakes;
apple = new Product("Apples (4 pack)", 1.20, 1);
apples = new Product("Apples (4 pack)", 1.20, 2);
milk = new Product("Milk (1l)", 0.75, 1);
caulk = new Product("Caulk (1l)", 6.84, 1);
ice = new Product("Ice (1kg)", 4.30, 1);
snakes = new Product("Snake (5m)", 32.0, 1);
newCart.add(apple);
newCart.add(apple);
newCart.add(apple);
newCart.add(apple);
newCart.add(caulk);
newCart.add(milk);
System.out.println(newCart);
}
}
The output is
4 * GBP .75 Milk (1l) = GBP 3.00
I'm guessing something has gone wrong in my toString() and add() methods, but I can't tell what.
You need to implement Product.toString() as follow for example :
#Override
public String toString() {
DecimalFormat format = new DecimalFormat("#.00");
return String.format("%d * GBP %5s %15s= GBP %5s", quantity, format.format(price),
name, format.format(price * quantity));
}
And the ShoppingCart.toString() will use Product.toString() of each Product :
#Override
public String toString() {
double total = 0;
StringBuilder sb = new StringBuilder();
for (Product p : cart) {
sb.append(p.toString()).append("\n");
total += p.getTotalPrice();
}
sb.append(String.format("%s%33.2f", "Total :", total));
return sb.toString();
}
Finally you'll get :
8 * GBP 1,20 Apples (4 pack)= GBP 9,60
2 * GBP 6,84 Caulk (1l)= GBP 13,68
4 * GBP ,75 Milk (1l)= GBP 3,00
4 * GBP ,75 Milk (1l)= GBP 3,00
Total : 29,28
As now, when you set a new quantity it affects the initial object as it's referenced in the list, you need to add a copy of in the list, also change the loop : when you find the same product, change the quantity then return, and **only at the end of the loop* if you haven't find the product you'll add it, you need to wait to check all the existant products :
public void add(Product p) {
if (cart.size() > 0) {
for (Product product : cart) {
if (product.getName().equals(p.getName()) && product.getPrice() == p.getPrice()) {
product.setQuantity(product.getQuantity() + p.getQuantity());
return;
}
}
cart.add(new Product(p));
} else {
cart.add(new Product(p));
}
}
And in Product class, a copy constructor :
public Product(Product p) {
this.quantity = p.quantity;
this.price = p.price;
this.name = p.name;
}
Also, don't make the list static, each shoppingCart has its own list
private ArrayList<Product> cart;
public ShoppingCart() {
cart = new ArrayList<>();
}
In toString() method you have a for loop but you are just keeping last item data in the loop. you should correct it like this:
String name = "";
for (Product p: cart) {
quantity += p.getQuantity();
price += p.getPrice();
name += p.getName();
total += p.getTotalPrice();
}
I have two classes Dog.java and DogSerach.java and I want to print dog detail using HashMap. I studied duplicate of this question get string value from HashMap depending on key name and also studied Oracle doc http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html, but still can not figure it out.
I have tried in DogSearch.java
for (String key: dogs.keySet()) {
System.out.println("Registration number : " + key);
System.out.println("Detail : " + dogs.get(key));
}
But I get
Registration number : 1003
Detail : Dog [name=Luca, breed=Labrador, registrationNumber=1003]
Registration number : 1002
Detail : Dog [name=Gracie, breed=Rottweiler, registrationNumber=1002]
Registration number : 1001
Detail : Dog [name=Max, breed=German Shepherd, registrationNumber=1001]
I want to print like this
Registration number: 1001
Name: Max
Breed: German Shepherd
... etc.
DogSearch.java
public class DogSearch {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
Map<String, Dog> dogs = new HashMap<String, Dog>();
Dog max = new Dog("Max", "German Shepherd", "1001");
Dog gracie = new Dog("Gracie", "Rottweiler", "1002");
Dog luca = new Dog("Luca", "Labrador", "1003");
dogs.put(max.getRegistrationNumber(), max);
dogs.put(gracie.getRegistrationNumber(), gracie);
dogs.put(luca.getRegistrationNumber(), luca);
System.out.println("List of dogs by name: ");
for (String key: dogs.keySet()) {
System.out.println("Registration number : " + key);
System.out.println("Breed : " + dogs.get(key));
}
}
}
Dog.java
class Dog {
private String name;
private String breed;
private String registrationNumber;
public Dog(String name, String breed, String registrationNumber) {
this.name = name;
this.breed = breed;
this.registrationNumber = registrationNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public String getRegistrationNumber() {
return registrationNumber;
}
public void setRegistrationNumber(String registrationNumber) {
this.registrationNumber = registrationNumber;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((breed == null) ? 0 : breed.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((registrationNumber == null) ? 0 : registrationNumber.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Dog other = (Dog) obj;
if (breed == null) {
if (other.breed != null)
return false;
} else if (!breed.equals(other.breed))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (registrationNumber == null) {
if (other.registrationNumber != null)
return false;
} else if (!registrationNumber.equals(other.registrationNumber))
return false;
return true;
}
#Override
public String toString() {
return "Dog [name=" + name + ", breed=" + breed + ", registrationNumber=" + registrationNumber + "]";
}
}
You can just do:
for (String key: dogs.keySet()) {
System.out.println("Registration number : " + key);
System.out.println("Name: " + dogs.get(key).getName());
System.out.println("Breed: " + dogs.get(key).getBreed());
}
}
With Java 8 streams you can sort the map by the names of your dogs.
Map<String, Dog> result = dogs.entrySet().stream()
.sorted(Map.Entry.comparingByValue(new MyComparator()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
and then loop through the result map.
for (String key: result.keySet()) {
System.out.println("Registration number : " + key);
System.out.println("Name: " + dogs.get(key).getName());
System.out.println("Breed: " + dogs.get(key).getBreed());
}
}
And you need a Comparator class
public class MyComparator implements Comparator<Dog>{
public int compare(Dog s1, Dog s2) {
return s1.getName().compareTo(s2.getName());
}
}
There are multiple ways to achieve what you want:
The first one is to change the toString() method of your Dog.java. When using System.out.println(), java uses the toString() method when passing classes as arguments.
So changing your toString() to :
return "Name: " + name + "\n" +
"Breed: " + breed;
should do the trick.
The second way is to change what you print in your for loop.
an example of what you can do is:
for (String key: dogs.keySet()) {
System.out.println("Registration number : " + key);
Dog dog = dogs.get(key);
System.out.println("Name : " + dog.getName());
System.out.println("Breed: " + dog.getBreed());
}
why don't you create a method in class Dog and write the implementation the way would like to print!
So here you just need
for (String key: dogs.keySet()) {
System.out.println(dogs.get(key).getPrintString());
}
This will go in Dog class
public String getPrintString() {
return "Registration number : "+ getRegistrationNumber() +"\nName: " +getName() +"\nBreed:"+getBreed(); // This can be optimized further using StringBuffer
}