I have a shopping list that contains a set number of items. Through user input, I want to ask the user how many of the same item would they like to add to their shopping bag.
For Example: I have the following ArrayList newProduct = {"apple","orange","banana"};. Now I want to prompt the user to choose which (and how many) of the items in newProduct would they like to add into a second array called bag. If the user chooses a an apple with a quantity of 2, then 2 apples would be added to bag and it would look like this bag = {"apple","apple"};
I tried to useoperands that would duplicate the value. But it didn't work very well. What is wrong with this?
import java.util.*;
import java.util.stream.IntStream;
public class Bag extends Price {
static Scanner input = new Scanner(System.in);
#SuppressWarnings("unused")
private static String newName;
private int choice;
public ArrayList<String> bag = new ArrayList<String>();
public List<Double> bagPrice = new ArrayList<Double>();
public void addProduct() {
Bag item = new Bag();
while (sum(bagPrice) <= 58.00) {
System.out.println("Choose a Priority");
item.choice = input.nextInt();
System.out.println("Choose Quantity");
int quantity = input.nextInt();
if (IntStream.of(newPriority).anyMatch(x -> x == item.choice)) {
item.bag.add(newProduct.get(item.choice));
System.out.print("PRICE $ " + Double.valueOf(formatter.format(price.get(item.choice - 1))));
bagPrice.add(price.get(item.choice - 1));
System.out.println("BAG: " + item.bag);
System.out.println("TOTAL : " + Double.valueOf(formatter.format(sum(bagPrice))));
} else {
System.out.println("Priority Does Not Exist");
}
}
}
public double sum(List<Double> bagPrice) {
double sum = 0.00;
for (double s : bagPrice) {
sum = sum + s;
}
return sum;
}
}
I'm fairly new to programming so if there is any better suggestion I would greatly appreciate it.
You might have to use clone() method to get a copy, hope this would be helpful Clone method for Java arrays
Related
I am trying to have the user input a letter grade and then convert it to an integer that is stored in a separate public class. I used several if loops to try to make this happen, but I can't get it to work. Any ideas what I am doing wrong and how to fix or work around it? When I run the code how it is now, all I can get for output is 0. I have a feeling that this is probably because I am trying to store the value in a separate class, but I don't know how to make it work.
import java.util.Scanner;
class Courses {
static public String letterGrade;
static public int numberGrade;
static public int creditValue;
static public float GPA;
}
public class GradeCruncher {
static Scanner userinput = new Scanner(System.in);
public static void main(String[] args) {
int numOfCourses;
int courseNum = 0;
System.out.println("How many courses would you like to input?");
numOfCourses = userinput.nextInt();
Courses[] course = new Courses[numOfCourses];
while (courseNum < numOfCourses) {
System.out.println("Enter info for course " + courseNum);
System.out.println("How many credits is this course worth?");
course[courseNum].creditValue = userinput.nextInt();
System.out.println("What is your current letter grade for this course?");
userinput.next();
course[courseNum].letterGrade = userinput.nextLine();
String aPlus = "a+", a = "a", aMinus = "a-", bPlus = "b+", b = "b", bMinus = "b-", cPlus = "c+", c = "c",
cMinus = "c-", dPlus = "d+", d = "d", dMinus = "d-", f = "f";
if (f.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 0;
}
else if (dMinus.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 60;
}
else if (d.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 63;
}
else if (dPlus.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 67;
}
else if (cMinus.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 70;
}
else if (c.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 73;
}
else if (cPlus.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 77;
}
else if (bMinus.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 80;
}
else if (b.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 83;
}
else if (bPlus.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 87;
}
else if (aMinus.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 90;
}
else if (a.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 93;
}
else if (aPlus.equalsIgnoreCase(Courses.letterGrade)) {
course[courseNum].numberGrade = 100;
}
System.out.println(course[courseNum].numberGrade);
courseNum++;
continue;
}
System.out.println(course[courseNum].numberGrade);
Courses.GPA = ((course[0].numberGrade * course[0].creditValue) + (course[1].numberGrade * course[1].creditValue)) / (course[0].creditValue + course[1].creditValue);
System.out.println(Courses.GPA);
}
}
I have found several issues in your code, besides the things already stated in the comments:
Although you create an array of Courses, you never actually create any Courses objects, which you add to the array. When there are no Courses in your array, you also cannot assign your variables.
You should use a Map to avoid having to use all of these ifs.
The naming of your class is misleading. The array should be called courses and the class should be called Course.
I tried to rebuild your code so that it makes sense to me and works as I think it should.
import java.util.HashMap;
import java.util.Scanner;
class Course {
public String letterGrade;
public int numberGrade;
public int creditValue;
//public float GPA; // this should not be part of your Course class
Course(int credits, int gradeNum, String gradeLet) {
letterGrade = gradeLet;
numberGrade = gradeNum;
creditValue = credits;
}
}
public class GradeCruncher {
static Scanner userInput = new Scanner(System.in);
static HashMap<String, Integer> gradeMap = getGradeMap();
public static void main(String[] args) {
int numOfCourses;
int courseNum = 0;
System.out.println("How many courses would you like to input?");
numOfCourses = userInput.nextInt();
// create the array to store the courses
Course[] courses = new Course[numOfCourses];
// loop to get all courses
for (; courseNum < numOfCourses; courseNum++) {
System.out.println("Enter info for course " + courseNum);
System.out.println("How many credits is this course worth?");
// Get the credits for this course from input and save it temporarily
int tempCredits = userInput.nextInt();
System.out.println("Credits is " + tempCredits);
System.out.println("What is your current letter grade for this course?");
// this is needed so that the scanner removes the newline (\n) from the input
userInput.nextLine();
// Get the letter grade for this course from input and save it temporarily
String tempLetterGrade = userInput.nextLine();
System.out.println("Letter grade is " + tempLetterGrade);
// Retrieve the number grade from the map and save it
int tempNumberGrade = gradeMap.get(tempLetterGrade);
// Create the Course object with the input values and save it in the courses array
courses[courseNum] = new Course(tempCredits, tempNumberGrade, tempLetterGrade);
}
// All courses built
// Calculate GPA
double gpa = 0.0;
int overallCreditValue = 0;
for (int i = 0; i < courses.length; i++) {
gpa += (courses[i].numberGrade * courses[i].creditValue);
overallCreditValue += courses[i].creditValue;
}
gpa = gpa / overallCreditValue;
System.out.println("GPA Calculated: " + gpa);
}
private static HashMap<String, Integer> getGradeMap() {
HashMap<String, Integer> gradeMap = new HashMap<String, Integer>();
gradeMap.put("a+", 100);
gradeMap.put("a", 93);
gradeMap.put("a-", 90);
gradeMap.put("b+", 87);
gradeMap.put("b", 83);
gradeMap.put("b-", 80);
gradeMap.put("c+", 77);
gradeMap.put("c", 73);
gradeMap.put("c-", 70);
gradeMap.put("d+", 67);
gradeMap.put("d", 63);
gradeMap.put("d-", 60);
gradeMap.put("f", 0);
return gradeMap;
}
}
Explanation:
The letter and number grades are mapped in a map. The Course Class is now structured, so that the contents are input via the constructor. First all the inputs are retrieved from the user for each course and stored temporarily. When all the course info is retrieved, the Course object is created with this information and then stored in the courses array. When all courses are created, the average is calculated (according to the way you did it) and printed to the output.
Input and output:
How many courses would you like to input?
2
Enter info for course 0
How many credits is this course worth?
5
What is your current letter grade for this course?
a+
Enter info for course 1
How many credits is this course worth?
5
What is your current letter grade for this course?
a
GPA Calculated: 96.5
(f.equalsIgnoreCase(Courses.letterGrade)) ----- is wrong.
Replace Courses.letterGrade with Course[coursenum].lettergrade
remove continue,no need of that .
better design is to use switch statement.
Courses is a Class not a object u cannot store in it. You have created a object of type Courses 'courses' in this u can store.
replace Courses.Gpa to a integer variable.
I am trying to write a shopping list program where the user enters in items on a shopping list with corresponding prices. I have used a String array for the items on the shopping list and a double array for the prices. At the end, the program should print out the most expensive item and the least expensive item.
To do this I made a copy of the price array. Then sorted the original price array using Arrays.sort() so it rearranged in ascending order. After that, I used a for loop to compare the duplicate price array with the sorted original array and when the value in the duplicate is the same as the lowest/highest value in the sorted array I printed the shopping item in the corresponding position from the string array.
This doesn't seem to work exactly as the String being printed doesn't always correspond to the exact position, as it should according to my logic. I cannot figure out where I'm going wrong. I think the problem lies in the getCheapestItem() and getMostExpensiveItem() methods.
Edit:
There might be better ways to do it, like using List or ArrayList, but I need to solve it using Arrays only.
Main class:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static Scanner scanner = new Scanner(System.in);
static int listSize;
static String[] sl;
static double[] price;
static double [] price_duplicate;
public static void main(String[] args) {
Fruit fruit = new Fruit();
shoppingList();
sl = new String[listSize];
price = new double[listSize];
//Loop asking user to enter items and prices
for(int i = 0; i <= listSize - 1; i++)
{
System.out.println("Enter item " + (i+1) + ":");
fruit.setName(scanner.nextLine());
sl[i] = fruit.getName();
System.out.print("Price of " + sl[i] + ":");
fruit.setPrice(scanner.nextDouble());
scanner.nextLine(); //calling nextLine() to get rid of the newline character
price[i] = fruit.getPrice();
}
//Loop printing items and their prices
System.out.println();
System.out.println("-Your shopping list-");
for(int i = 0; i <= listSize - 1; i++)
{
System.out.println(sl[i] + " cost " + price[i]);
}
System.out.println();
//Duplicate the price array
price_duplicate = price;
//Order the array in ascending order so as to be able to easily access lowest and highest values in the array
Arrays.sort(price);
//Identify the cheapest and most expensive items on the shopping list
getCheapestItem();
getMostExpensiveItem();
}
static int shoppingList(){
System.out.print("Enter the number of items in your shopping list:");
listSize = scanner.nextInt();
scanner.nextLine(); //calling nextLine() to get rid of the newline character
return listSize;
}
//Method to match the lowest price in the sorted array to its equivalent value in the duplicate of the original array and print the corresponding string from the sl array, thus identifying the cheapest item on the list
static void getCheapestItem(){
Arrays.sort(price);
for(int i = 0; i < price_duplicate.length; i++){
if(price_duplicate[i] == price[0])
{
System.out.println(sl[i] + " cost(s) " + price[0] + " and is/are the cheapest item(s) on the list.");
}
}
}
//Method to Match the highest price in the sorted array to its equivalent value in the duplicate of the original array and print the corresponding string from the sl array, thus identifying the most expensive item on the list
static void getMostExpensiveItem(){
Arrays.sort(price);
for(int i = price_duplicate.length - 1; i >= 0; i--){
if( price_duplicate[i] == price[price.length - 1])
{
System.out.println(sl[i] + " cost(s) " + price[price.length -1] + " and is/are the most expensive item(s) on the list.");
}
}
}
}
Fruit class:
public class Fruit {
private String name;
private double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
I guess your problem lies in making a copy/duplicate of the price array. You are using price_duplicate=price; which actually not making copy of the price array contents, but just references/points to the same price array object with the duplicate array.
As a result, when you are sorting the original price array, your duplicate array also get sorted. There are several ways to copy an array object to another.
But I would suggest you to use one of your existing code flow, when you are inserting the prices into the original price array, you can also insert them into the duplicate array.
After the price[i]=fruit.getPrice();just add price_duplicate[i]=fruit.getPrice();
And don't forget to initialize the duplicate array as like you initialized the original price array before.
I'm not sure why you are using two arrays, since that makes things more complicated. I would go for a single list static List<Fruit> fruits;.
Then reading the items could be simplified too:
for(int i = 0; i <= listSize - 1; i++)
{
System.out.println("Enter item " + (i+1) + ":");
name = scanner.nextLine();
System.out.print("Price of " + sl[i] + ":");
price = scanner.nextDouble();
scanner.nextLine(); //calling nextLine() to get rid of the newline character
fruits.add(new Fruit(name, price));
}
Of course this means Fruit needs a constructor that requires both name and price. name and price should be defined outside of the loop.
To do the sorting you could use a Comperator<Fruit>.
Comperator<Fruit> compareByPrice = (Fruit f1, Fruit f2) ->
f1.getPrice().compareTo(f2.getPrice());
To sort ascending:
Collections.sort(fruits, compareByPrice);
To sort descending:
Collections.sort(fruits, compareByPrice.reversed());
You don't have to complicate things. You can get cheapest and expensive fruits through fruit objects itself. Look at below example. Create list of Fruit objects. Than do Collections.sort. In Collections.sort you can provide your implementation of Comparator (way to sort any object). In you case sorting has to be done by price. After sorting you can find cheapest fruit in first index and expensive one in last index
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Fruit> fruitList = new ArrayList<>();
fruitList.add(new Fruit("orange", 3.2));
fruitList.add(new Fruit("apple", 9.5));
fruitList.add(new Fruit("banana", 7.4));
fruitList.add(new Fruit("grapes", 1.3));
Collections.sort(fruitList, new Comparator<Fruit>() {
#Override
public int compare(Fruit o1, Fruit o2) {
if (o1.getPrice() < o2.getPrice()) {
return -1;
} else if (o1.getPrice() > o2.getPrice())
{
return 1;
} else {
return 0;
}
}
});
System.out.println("Cheapest fruit " + fruitList.get(0).getName());
System.out.println("Expensive fruit " + fruitList.get(3).getName());
}
}
You use illegal organisation. You should split your code with following parts:
Implement Fruit class, that contain full infromation about single fruit
Implement method, that using console retrieves list of fruits
Define actions to be applied for given list of fruits: get fruits with minimum/maximum prices
Output results.
This is Fruit class implementation. It is immutable.
public final class Fruit {
private final String name;
private final double price;
public Fruit(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
Functions, that receive List<Fruit> and retrieve fruits that reuiqred specific conditions.
Note that price is double value, hence it should be compared correctly, using Double.compare(one, two) == 0 method instead of using one == two.
private static final Function<List<Fruit>, List<Fruit>> GET_CHEAPEST = fruits -> {
final double minPrice = fruits.stream().mapToDouble(Fruit::getPrice).min().orElse(Double.NaN);
return fruits.stream().filter(fruit -> Double.compare(fruit.getPrice(), minPrice) == 0).collect(Collectors.toList());
};
private static final Function<List<Fruit>, List<Fruit>> GET_MOST_EXPENSIVE = fruits -> {
final double maxPrice = fruits.stream().mapToDouble(Fruit::getPrice).max().orElse(Double.NaN);
return fruits.stream().filter(fruit -> Double.compare(fruit.getPrice(), maxPrice) == 0).collect(Collectors.toList());
};
This is method that use Scanner to receive all information about all fruits. Do not forget to close Scanner.
private static List<Fruit> getFruits() {
try (Scanner scan = new Scanner(System.in)) {
System.out.print("Enter the number of items in your shopping list: ");
int total = scan.nextInt();
List<Fruit> fruits = new ArrayList<>(total);
for (int i = 1; i <= total; i++) {
System.out.println("Enter item " + i + ':');
System.out.print("Name: ");
String name = scan.nextLine();
System.out.print("Price: ");
double price = scan.nextDouble();
fruits.add(new Fruit(name, price));
System.out.println();
}
return fruits;
}
}
And finally client code. I believe that now it is pretty simple to realize.
List<Fruit> fruits = getFruits();
List<Fruit> cheapestFruits = GET_CHEAPEST.apply(fruits);
List<Fruit> mostExpensiveFruits = GET_MOST_EXPENSIVE.apply(fruits);
System.out.println("Cheapest fruits:");
cheapestFruits.forEach(fruit -> System.out.format("%s costs %.2f\n", fruit.getName(), fruit.getPrice()));
System.out.println();
System.out.println("Most expensive fruits:");
mostExpensiveFruits.forEach(fruit -> System.out.format("%s costs %.2f\n", fruit.getName(), fruit.getPrice()));
So.. I took an alternative way to process the information. Which I believe is worth you looking at. Although it won't satisfy your problem it will create a working example.
Scanner or anything that involves parsing String to Integer/Double/Short/etc.. has the issue that the String must PERFECTLY equal that value.
In your example you do Scanner.parseDouble(String); The problem is if the user inputs a non decimal value. Your program will crash. On top of that if the decimal is out of precision it will return an invalid or non expected result.
To get around this we use a char array or a value type that far exceeds our needs. In my situation I used a long value. Which has a maximum numeric amount of 9,223,372,036,854,775,807. We don't need anywhere near that amount so it's safe to lock the item to maximum price of 999,999,999.99 and it'll fit millions of times into that value. Then when it comes time to display this value we can convert it into text useable for reading as a price.
I also took on a non array approach to give you insight on another way to find, store, and display the lowest and highest cost items. I also gave you total items and total shopping cost. Hopefully you can use some of these examples for future code.
Another thing to point out his how I converted the String of numbers to a value. There's many way to go about this, but given this situation I choose to loop backwards from the known decimal index or length of string if no decimal was given. We convert the character from 0-9 to a value of 0 to 9. This was done by taking it's char value and taking 48 off it. If the value didn't equal a number between 0 and 9 we skipped it. If it did though we added it to our total value. We started with 100 as our multiplier so 98.76 would give us 9800 price value. Then we add the change which is 99 so gives us a total number of 9876. When we want to convert this into a price. We do 9876 / 100 = 98 and display the 98. Then take 9876 and minus (98 * 100) = 76. So then we display "." and "76". This gives us safe cost displaying and we can support any amount from 0 to 999,999,999.99 safely.
_
import java.util.Scanner;
public class ShoppingList
{
private static long LOWEST_ITEM_COST = Long.MAX_VALUE;
private static long HIGHEST_ITEM_COST = -1;
private static long TOTAL_COST = 0;
private static int TOTAL_ITEMS = 0;
private static String LOWEST_ITEM_NAME;
private static String HIGHEST_ITEM_NAME;
public static void main(String[] args)
{
System.out.print("\nSyntax: FOODNAME PRICE, I.e. Apples $8.50");
while (true)
{
Scanner sc = new Scanner(System.in);
System.out.print("\nEnter a food: ");
String split[] = sc.nextLine().split(" ");
if (split.length > 2)
{
}
if (split.length == 2)
{
String name = split[0];
int length = split[1].length();
int decimal_position = -1;
for (int j = length; --j >= 0; )
{
if (split[1].charAt(j) == '.')
{
decimal_position = j;
break;
}
}
if (decimal_position != -1)
length = decimal_position;
long dollars = 0;
long change = 0;
int place = 100;
for (int c = length; --c >= 0; )
{
int value = (int)split[1].charAt(c) - 48;
if (value < 0 || value > 10)
continue;
if (place == 1000000000) //1 Billion is too large to process stop here!
{
System.out.print("\nPrice Amount exceeds $999,999,999.99 limitation! You entered: " + split[1]);
continue;
}
value *= place;
place *= 10;
dollars += value;
}
place = 10;
if (decimal_position != -1 && (split[1].length() - 3 >= decimal_position))
{
for (int c = decimal_position; c < split[1].length(); ++c)
{
int value = (int)split[1].charAt(c) - 48;
if (value < 0 || value > 10)
continue;
value *= place;
place -= 9;
change += value;
if (place < 0)
break;
}
}
System.out.print("\nItem: " + name + " was added to the shopping cart. Cost: $" + (dollars / 100) + '.' + ((change < 10) ? (change + '0') : (change)));
dollars += change;
if (dollars < LOWEST_ITEM_COST)
{
LOWEST_ITEM_COST = dollars;
LOWEST_ITEM_NAME = name;
}
if (dollars > HIGHEST_ITEM_COST)
{
HIGHEST_ITEM_COST = dollars;
HIGHEST_ITEM_NAME = name;
}
TOTAL_ITEMS++;
TOTAL_COST += dollars;
} else {
if (split.length == 1 && split[0].toLowerCase().contains("done"))
{
break;
}
System.out.print("\nSyntax: FOODNAME PRICE, E.g. IceCream 8.50");
System.out.print("\nTo Finish The Shopping List Simply type: DONE");
continue;
}
}
if (TOTAL_ITEMS == 0)
{
System.out.print("\nNothing Was Added To Your Shopping List Today..");
return;
}
long dollars = HIGHEST_ITEM_COST / 100;
long change = HIGHEST_ITEM_COST - (dollars * 100);
System.out.print("\nHighest Cost Item: " + HIGHEST_ITEM_NAME + " , Costed: " + dollars + '.' + change + ((change < 10) ? '0' : ""));
dollars = LOWEST_ITEM_COST / 100;
change = LOWEST_ITEM_COST - (dollars * 100);
System.out.print("\nLowest Cost Item: " + LOWEST_ITEM_NAME + " , Costed: " + dollars + '.' + change + ((change < 10) ? '0' : ""));
dollars = TOTAL_COST / 100;
change = TOTAL_COST - (dollars * 100);
System.out.print("\nTotal Items Bought: " + TOTAL_ITEMS + " , With a total cost of $" + dollars + '.' + change + ((change < 10) ? '0' : ""));
}
}
my question is how would I sort the arrayofnames and arrayofdownloads so they're in ascending order and each name matches with it corresponding number of downloads. i've been trying for 4 hours and i can't seem to wrap my head around it
thanks
import java.util.*;
import java.util.stream.*;
public class short6
{
public static void main(String[] args)
{
String[] arrayofnames = new String[4];
int[] arrayofdownloads = new int[4];
printmessage(arrayofnames, arrayofdownloads);
details(arrayofnames, arrayofdownloads);
System.exit(0);
}
public static void printmessage(String[] arrayofnames, int[] arrayofdownloads)
{
Scanner scanner = new Scanner(System.in);
int totalDownloads = 0;
for (int i = 0; i < arrayofnames.length; i++)
{
System.out.println("What is track " + (i + 1));
arrayofnames[i] = scanner.nextLine();
System.out.println("How many thousands of times has it been downloaded? ");
arrayofdownloads[i] = Integer.parseInt(scanner.nextLine());
}
Arrays.sort(arrayofnames);
Arrays.sort(arrayofdownloads);
System.out.println("The track downloaded the most is " + arrayofdownloads[0]+".");
}
public static void details(String[] arrayofnames, int[] arrayofdownloads)
{
int totaldownloads = IntStream.of(arrayofdownloads).sum();
System.out.println("The track downloaded the most is " + arrayofdownloads[0]+".");
System.out.println("The total number of downloads of these 4 tracks was " + totaldownloads * 1000 +".");
System.out.println("\nThe details of the downloads are");
for (int i = 1; i < arrayofnames.length; i++)
{
System.out.println(arrayofnames[i]);
System.out.println((arrayofdownloads[i]));
}
}
}
I'd start creating a Song (e.g.) class that contains both the song name, and the number of downloads:
public class Song {
private String name;
private int downloads;
public Song(String name, int downloads) {
this.name = name;
this.downloads = downloads;
}
public String getName() {
return this.name;
}
public int getDownloads() {
return this.downloads;
}
}
And then, create an array of songs:
Song[] arrayOfSongs = new Song[4];
And load it from the input:
arrayOfSongs[i] = new Song(scanner.nextLine(), Integer.parseInt(scanner.nextLine()));
Now you just need to sort it using a comparator:
Arrays.sort(arrayOfSongs, new Comparator<Song> () {
public int compare(Song o1, Song o2) {
// Sorting by name
return o1.getName().compareTo(o2.getName());
}
});
Or, as #Benoit has said in the comments, it would be even easier this way (Java 8 or up):
Arrays.sort(arrayOfSongs, Comparator.comparing(Song::getName));
And your done, just printing the objects (a toString method can be helpful here) you have the information sorted.
Edit: to read the input writing the questions, you just need to store the values in variables e.g.
System.out.println("What is track " + (i + 1));
String songName = scanner.nextLine();
System.out.println("How many thousands of times has it been downloaded? ");
int songDownloads = Integer.parseInt(scanner.nextLine());
arrayOfSongs[i] = new Song(songName, songDownloads);
Or you can just implement setter methods in the Song class and create a constructor with no parameters, so you can set the values as you are reading them.
thanks for the reply, so I've figured that i can use a for loop to ask the questions for song name and number of downloads. what im finding hard is putting their response in each array from 1-4 and saving dong name in the correct field of the song record and same for number of downloads?
public static void printmessage(song[] arrayOfSongs)
{
Scanner scanner = new Scanner(System.in);
int totalDownloads = 0;
for (int i = 0; i < arrayOfSongs.length; i++)
{
System.out.println("What is track " + (i + 1));
// store in array x name field
System.out.println("How many downloads does this track have? ");
//store in array x downloads field
}
I'm trying to use the items of one array within a for loop that is looping through another array. For example, I want to display the item name (an array that already exists) when asking for the price of each of these items. "What price is item[i]". I don't think you can use item[i] in this instance. I've also tried using a get method and using a counter variable, but I must be doing something wrong.
The readPrice portion isn't working - specifically the item[i]. Does anyone have a suggestion how to accomplish the same thing without using item[i]?
I'm new to java, so I'm sorry if this is an obvious answer, but I would really appreciate the help!
Here is my code:
private String[] items;
private int[] priority;
private double[] price;
public void readInput()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("You will need to enter seven shopping items.");
items = new String[7];
for (int i = 0; i < items.length; i++)
{
System.out.println("Enter an item: ");
items[i] = keyboard.nextLine();
}
}
**public void readPrice()**
{
price = new double[7];
Scanner keyboard = new Scanner(System.in);
for(int i = 0; i < price.length; i++)
{
System.out.println("Enter the price for " + **items[i]**);
price[i] = keyboard.nextDouble();
}
}
you can make a class Item.
public class Item {
String name;
double price;
public void setName(String name) {
this.name = name;
}
public void setPrice(double price) {
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
#Override
public String toString() {
return "Item{" + "name=" + name + ", price=" + price + '}';
}
}
After create an object of class Item
public class TestPaper {
public static void main(String[] args) {
Item item;
Item[] itemTable = new Item[7];
ArrayList<Item> itemlist = new ArrayList<>();
for (int i = 0; i < 7; i++) {
item = new Item();
//set value
item.setName("item1");
item.setPrice(200);
//store the object to a table or an arraylist
itemTable[i] = item;
itemlist.add(item);
}
for (Item temp : itemTable) {
System.out.println(temp.toString());
}
}
}
This is better solution, but I will answer you with your code.
You have 7 items, so you can print the items like this:
private String[] items;
private int[] priority;
private double[] price;
public void readInput()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("You will need to enter seven shopping items.");
items = new String[7];
for (int i = 0; i < items.length; i++)
{
System.out.println("Enter an item: ");
items[i] = keyboard.nextLine();
}
}
**public void readPrice()**
{
price = new double[7];
Scanner keyboard = new Scanner(System.in);
for(int i = 0; i < price.length; i++)
{
System.out.println("Enter the price for " + **items[i]**);
price[i] = keyboard.nextDouble();
}
public void printdata(){
for(int I=0; I<7; I++){
System.out.println("item name: " +item[i] +" price: "+price[i])
}
}
Alright, well here's the answer for you. There are two main approaches to this: either pass the object items as a parameter, or make it global.
Global Variable Approach
For the global approach, which you seem to sort of already be doing, first declare your object as a field for your class:
class MyClass
{
private String[] items = new String[7];
//...Rest of class goes here
}
Now you can access it from your two methods as you wish.
public readInput()
{
// Add stuff to items
items[0] = "hi";
}
public readPrice()
{
// Read from items
System.out.println(items[0]);
}
Method Parameter Approach
Now if you want to actually pass an object from one method to another but don't want it to be accessible to any other methods, you can make it a parameter like this:
public readPrice(String[] items)
{
// Read from items
System.out.println(items[0]);
}
And then you can call the method from somewhere else passing specific instances of the object type.
public inputPrice()
{
String[] items = new String[7];
// Add stuff to items
items[0] = "hi";
this.readPrice(items);
}
Passing parameters is especially useful if you want to call a single method several times, but have it act on different inputs.
Please provide a stacktrace of the occurring error to make everyone happy. I personally would create a Map to assign a price to an item.
Code
package test;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
public class Items {
private int itemsLength = 10;
private Map<String, Double> items = new HashMap<>();
public Items() {
System.out.println("Please fill in the details below: ");
for(int i = 0; i < itemsLength; i++) {
Scanner in = new Scanner(System.in);
String itemName;
Double price;
System.out.println("Enter an item name: ");
itemName = in.nextLine();
System.out.println(String.format("Enter %s's price: ", itemName));
price = in.nextDouble();
items.put(itemName, price);
}
System.out.println("Here are your items: ");
System.out.println("+------------------------+");
System.out.println(String.format("|%-10s | %-10s %-6s", "Item", "Price", "|"));
for (Entry<String, Double> entry : items.entrySet()) {
System.out.println(String.format("|%-10s | %-10s %-6s", entry.getKey(), entry.getValue(), "|"));
}
System.out.println("+------------------------+");
}
}
Output
Please fill in the details below:
Enter an item name:
Shoes
Enter Shoes's price:
20
Enter an item name:
Shirt
Enter Shirt's price:
20
Enter an item name:
Necklace
Enter Necklace's price:
50
Enter an item name:
Bracelet
Enter Bracelet's price:
30
Enter an item name:
Socks
Enter Socks's price:
5
Enter an item name:
Flip-flops
Enter Flip-flops's price:
10
Enter an item name:
Soda
Enter Soda's price:
2
Enter an item name:
Diamonds
Enter Diamonds's price:
20000
Enter an item name:
Weird Item
Enter Weird Item's price:
99999
Enter an item name:
Another Weird Item
Enter Another Weird Item's price:
99999
Here are your items:
+------------------------+
|Item | Price |
|Necklace | 50.0 |
|Another Weird Item | 99999.0 |
|Shirt | 20.0 |
|Bracelet | 30.0 |
|Diamonds | 20000.0 |
|Weird Item | 99999.0 |
|Shoes | 20.0 |
|Socks | 5.0 |
|Soda | 2.0 |
|Flip-flops | 10.0 |
+------------------------+
P.S: This is my first response, sorry if its not pretty
Edit: If you want to keep the order when outputting then construct a TreeMap instead of a HashMap.
I am a java beginner and I am coding a program that gets the name of the item, units of that item, price/unit and the total price. I am trying to put those values in different arrays
so I can access them later when I create a sort of a receipt but I don't know how to assign those values in array positions and then access those same positions without having to hard-code. A loop is the best option but I dont know how to set this thing up. Help and suggestions would really be appreciated. Keep in mind that I cant do advanced stuff like matrices and 3D arrays. If you can keep it simple it would be awesome.
This is the main class, I have a tester class with main() that runs userInput() and menu() but theres no point in putting that in because its only 2 lines of code.
import java.util.Scanner;
public class GroceryList {
// instance variables
Scanner Price, Items, NumItems, Units;
private double myGross, myNet;
private final double STATETAX;
private double totalPrice, unitPrice;
private String itemName;
private int totalUnits;
///////////////////////////////////////////// arrays I will use
private double[] totalPrice1;
private double[] unitPrice1;
private String[] itemName1;
private int[] totalUnits1;
public GroceryList()
{
STATETAX = 0.06;
double[] totalPrice = new double[50];
double[] unitPrice = new double[50];
String[] itemName = new String[50];
int[] totalUnits = new int[50];
}
public void userInput()
{
Scanner Price = new Scanner(System.in);
Scanner Items = new Scanner(System.in);
Scanner Units = new Scanner(System.in);
Scanner NumItems = new Scanner(System.in);
int u, c, totalItems;// c is the number of items that has to equal totalItems in order for the loop to break
double price;
String item;//gets the name of the item
c=0;
System.out.println("Welcome to Grocery List ! \n");
System.out.print("Enter the total number of items you want to buy (not total units !) : ");
totalItems = NumItems.nextInt();
System.out.println();
do
{
c++ ;
System.out.print("Enter the item name : ");
item = Items.nextLine();
System.out.print("Enter the units of " + item + " you want to buy : ");
u = Units.nextInt();
System.out.print("Enter the price of a/n " + item + " : $");
price = Price. nextDouble();
/*this would make only one value appear at the receipt, which would be only one item name, one unit price, one price/unit, one total price and the other values calculated
would not appear on the receipt because you cant assign more than 1 value to a variable so thats why I need arrays.
*/
itemName = item;
totalUnits = u;
unitPrice = price;
calc(u,price,item);
}
while (c < totalItems);
}
public void calc(int u, double p, String i)
{
double total;//total amount of $ for 1 item
total = u*p;
System.out.println("Total price of " + i + " : $" + total + "\n");
grossPay(total);
totalPrice = total;
}
public void grossPay(double total)
{
double gross;
myGross += total;
}
public double tax()
{
double temp;
temp = myGross*STATETAX;
myNet = myGross - temp;
return myNet;
}
public void menu()
{
System.out.printf("%-10s %6s %11s %11s" , "ITEM :" , "UNITS :" , "PRICE :" , "TOTAL :");
System.out.println();
System.out.printf("%-11s %2d %7s $%4.2f %5s $%2.2f", itemName, totalUnits,"", unitPrice,"", totalPrice);
System.out.println();
}
public void payment()
{
System.out.println("Amount before tax : $" + myGross);
System.out.println("Amount after tax : $" + tax());
}
}//end GroceryList
Let's start with a little restructure ;)
First of all, you really don't need the array totalPrice1, the total price is the total price, there's only one...(IMHO)
Instead of initialising the arrays in the constructor, you should initialise them in the userInput method, this is when you know how many items the user will want to enter. Otherwise you will run into problems if I want to enter 51 items ;)
System.out.println("Welcome to Grocery List ! \n");
System.out.print("Enter the total number of items you want to buy (not total units !) : ");
totalItems = NumItems.nextInt();
System.out.println();
unitPrice1 = new double[totalItems];
itemName1 = new String[totalItems];
totalUnits1 = new int[totalItems];
(nb- You have bug in your original code, in the constructor, you had declared the arrays as local variables, but used the wrong names any way, this would leave the instance fields uninitialised, raising a NullPointerException)
While it's certainly not an error, it would simpler to increment c at the end of the loop...
do {
//...
calc(u, price, item);
c++;
} while (c < totalItems);
This will mean you don't need to constantly keep adjusting the position for the arrays.
In you "collection" loop, you need to assign the values the user has entered to each array...
do {
//...
itemName1[c] = item;
totalUnits1[c] = u;
unitPrice1[c] = price;
//...
} while (c < totalItems);
Having said all that, it would actually be easier to use something like a for-next loop...
for (int c = 0; c < totalItems; c++) {
//...
}
IMHO...
Finally, when you're ready, you can print the receipt by simply looping through the arrays...
for (int index = 0; index < totalItems; index++) {
double itemCost = unitPrice1[index] * totalUnits1[index];
System.out.println(itemName1[index] + " # " + unitPrice1[index] + " x " + totalUnits1[index] + " = " + cost);
}
System.out.println("Total Cost: " + totalPrice);
Some feedback ;)
Having said all that, I would, personally, create yourself a simple Object which contained all the required information, for example;
public class ShoppingItem {
public String name;
public double unitPrice;
public double quantity;
}
Then, all you would need is a single array, for example...
//private double[] unitPrice1;
//private String[] itemName1;
//private int[] totalUnits1;
private ShopingItem[] items;
Then, as required, you would simply create a new instance of this item and fill it out, for example...
items[c] = new ShoppingItem();
items[c] = item;
items[c] = u;
items[c] = price;
//itemName1[c] = item;
//totalUnits1[c] = u;
//unitPrice1[c] = price;
And printing the receipt would look for like...
for (ShoppingItem item : items) {
double itemCost = item.unitPrice * item.quantity;
System.out.println(item.name + " # " + item.unitPrice + " x " + item.quantity + " = " + cost);
}
System.out.println("Total Cost: " + totalPrice);
For a more "advanced" output, I would encourage you to take a look a something like String#format and/or System.out.printf
Take a look at this example for some ideas ;)
Ideally you would (wrote this as I misread your meaning of sort):
Create an Object Item which has the fields name, totalPrice, unitPrice, totalUnits. Then in your grocery list you don't need to have 4 arrays, just one array of Items. Saves the dubious task of having to keep track of indices.
If you also create an ItemComparator class that implements Comparator you can define how they should be sorted and you can then sort your array using
Collections.sort(Arrays.asList(itemsList), new ItemComparator());
You also don't need four Scanners, you can use the same scanner since they are all on System.in