Hi guys I'm currently creating a program that allows the user to create an array, search an array and delete an element from an array. Looking at the LibraryMenu method, the first case where you create an array in the switch statement works fine, however the other ones create a "cannot find symbol error" when I try to compile.
My question is I want the search and delete functions to refer to the first switch case - the create Library array. Any help is appreciated, even if its likely from a simple mistake.
import java.util.*;
public class EnterLibrary
{
public static void LibraryMenu()
{
java.util.Scanner scannerObject =new java.util.Scanner(System.in);
LibraryMenu Menu = new LibraryMenu();
Menu.displayMenu();
switch (scannerObject.nextInt() )
{
case '1':
{
System.out.println ("1 - Add Videos");
Library[] newLibrary;
newLibrary = createLibrary();
}
break;
case '2':
System.out.println ("2 - Search Videos");
searchLibrary(newLibrary);
break;
case '3':
{
System.out.println ("3 - Change Videos");
//Change video method TBA
}
break;
case '4':
System.out.println ("4 - Delete Videos");
deleteVideo(newLibrary);
break;
default:
System.out.println ("Unrecognized option - please select options 1-3 ");
break;
}
}
public static Library[] createLibrary()
{
Library[] videos = new Library[4];
java.util.Scanner scannerObject =new java.util.Scanner(System.in);
for (int i = 0; i < videos.length; i++)
{
//User enters values into set methods in Library class
System.out.print("Enter video number: " + (i+1) + "\n");
String number = scannerObject.nextLine();
System.out.print("Enter video title: " + (i+1) + "\n");
String title = scannerObject.nextLine();
System.out.print("Enter video publisher: " + (i+1) + "\n");
String publisher = scannerObject.nextLine();
System.out.print("Enter video duration: " + (i+1) + "\n");
String duration = scannerObject.nextLine();
System.out.print("Enter video date: " + (i+1) + "\n");
String date= scannerObject.nextLine();
System.out.print("VIDEO " + (i+1) + " ENTRY ADDED " + "\n \n");
//Initialize arrays
videos[i] = new Library ();
videos[i].setVideo( number, title, publisher, duration, date );
}
return videos;
}
public static void printVidLibrary( Library[] videos)
{
//Get methods to print results
System.out.print("\n======VIDEO CATALOGUE====== \n");
for (int i = 0; i < videos.length; i++)
{
System.out.print("Video number " + (i+1) + ": \n" + videos[i].getNumber() + "\n ");
System.out.print("Video title " + (i+1) + ": \n" + videos[i].getTitle() + "\n ");
System.out.print("Video publisher " + (i+1) + ": \n" + videos[i].getPublisher() + "\n ");
System.out.print("Video duration " + (i+1) + ": \n" + videos[i].getDuration() + "\n ");
System.out.print("Video date " + (i+1) + ": \n" + videos[i].getDate() + "\n ");
}
}
public static Library searchLibrary( Library[] videos)
{
//User enters values to setSearch
Library titleResult = new Library();
java.util.Scanner scannerObject =new java.util.Scanner(System.in);
for (int n = 0; n < videos.length; n++)
{
System.out.println("Search for video number:\n");
String newSearch = scannerObject.nextLine();
titleResult.getSearch( videos, newSearch);
if (!titleResult.equals(-1))
{
System.out.print("Match found!\n" + newSearch + "\n");
}
else if (titleResult.equals(-1))
{
System.out.print("Sorry, no matches found!\n");
}
}
return titleResult;
}
public static void deleteVideo( Library[] videos)
{
Library titleResult = new Library();
java.util.Scanner scannerObject =new java.util.Scanner(System.in);
for (int n = 0; n < videos.length; n++)
{
System.out.println("Search for video number:\n");
String deleteSearch = scannerObject.nextLine();
titleResult.deleteVideo(videos, deleteSearch);
System.out.print("Video deleted\n");
}
}
public static void main(String[] args)
{
Library[] newLibrary;
new LibraryMenu();
}
}
I think this is a terrible design. You've mingled too many things together: user interface, logic, data structure.
Start by isolating your LibraryArray from the LibraryMenu. You shouldn't see any switch or input or output in it at all.
Java's an object-oriented language. Start thinking about your system in terms of objects. I don't see classes like Video and VideoCatalog. You'll find this system to be a lot easier to implement if you created them.
Looks like you've got a start:
package model;
public class Video {
private Long id;
private String title;
private String publisher;
private int durationSeconds;
private Date publicationDate;
// add ctors, getters, etc. Immutable? Could be...
// equals, hash code, toString
}
Keep your VideoCatalog free of user interface or I/O:
package model;
public interface VideoCatalog {
List<Video> find();
List<Video> find(String title);
List<Video> find(Date startDate, Date endDate) ;
Long save(Video video);
void update(Video video);
void delete(Video video);
}
Now you can have an implementation that uses any data structure you want:
package model;
public class VideoCatalogImpl implements VideoCatalog {
private Set<Video> videos;
// add implementations here.
}
You need to move the declaration of that array variable out of the scope of the first case, and up to someplace where the other cases can see it. Given the current structure of your code, it would be most convenient to make it a static member of the class -- i.e.,
public class EnterLibrary
{
Library[] newLibrary;
Then all the static methods of this class could share the one variable. But be sure to remove all the other declarations of the variable that appear in other methods, otherwise they still will be using separate variables, and bugs like that can be very hard to track down!
Library[] newLibrary; is defined in your case '1' only, you should define it in a wider scope, like your LibraryMenu method. Also, the Library[] newLibrary declared in your main is not called anywhere, and maybe you should add Null check in your search, print an delete methods.
Your constructor class must have the same name of your class and not have any modifier keywords in it. Also, when you create an object of your class, it wont use the static methods declared in there.
A note: when you work with your own declared arrays, it would be better that you declare a int variable to keep track of the actual size of the array. Note that array.length returns how many items the array can have, not how many items it already has.
I would redesign your definitions (not the code) to something like this:
//Note I changed the classname from EnterLibrary to LibraryMenu. Apparently you
//wanted a LibraryMenu class.
public class LibraryMenu {
private final int MAX_ITEMS = 50;
private Library[] videos;
private int size = 0;
//remove the static and void keyworkds from this method, so this will be
//the constructor.
public LibraryMenu() {
videos = new Library[MAX_ITEMS];
//the rest of your code here...
switch (scannerObject.nextInt()) {
//if you're reading an int, keep the constants in the case as int.
case 1:
//no need of brackets inside a case statement
//check that you can add an item in your Library array
//also, its not good to ask the user to add 4 (or N) videos in 1 round :).
if (size < MAX_ITEMS) {
Library video = addVideo();
videos[size++] = video;
}
break;
case 2:
break;
}
}
//remove the static keyword so the instance of your class can call the method.
public Library addVideo() {
Library video = new Library();
//your code to read data goes here...
//then fulfill the video and return it.
return video;
}
//The Library[] videos is declared in your class, so all other methods could
//use it without having to receive it as a parameter.
public void printVidLibrary() {
//your code goes here...
}
public Library searchLibrary() {
//your code goes here...
}
public void deleteVideo( Library[] videos) {
//your code goes here...
}
public static void main(String[] args) {
new LibraryMenu();
}
}
Try this,
Declare Library[] newLibrary; as an instance variable (at class scope), or as local variable before the switch statement.
Related
So I took everyone's feedback and information and have spent quite a bit of time trying to work on my code prior to submitting. Here are the changes that I have:
import java.util.*;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
class Automobiles {
String make;
String model;
String color;
int year;
int mileage;
int i;
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMileage() {
return mileage;
}
public void setMileage(int mileage) {
this.mileage = mileage;
}
public void setMake(String make) {
this.make = make;
}
public Automobiles() {
make = "";
model = "";
color = "";
year = 0;
mileage = 0;
}
public void Inventory(String make, String model, String color, int year, int mileage) {
System.out.println("Car is: " + make + " " + model + " " + color + " " + year + " " + mileage);
}
String getMake() {
return make;
}
}
public class AutomobileInventory {
public static void main(String[] args)
{
Automobiles[] carInventory = new Automobiles[15];
int i;
String fileName = "out.txt";
boolean quit = false;
String quit1 = "No";
Scanner scnr = new Scanner(System.in);
while (quit1 != "Yes") {
for(i=0; i<carInventory.length; i++) {
carInventory[i] = new Automobiles();
System.out.println("");
System.out.println("Please Enter the make of the vehicle: ");
carInventory[i].make = scnr.nextLine();
System.out.println("Please Enter the model of the vehicle: ");
carInventory[i].model = scnr.nextLine();
System.out.println("Please Enter the vehicle color: ");
carInventory[i].color = scnr.nextLine();
System.out.println("Please Enter the year of the vehicle: ");
carInventory[i].year = scnr.nextInt();
System.out.println("Please Enter the vehicle's mileage: ");
carInventory[i].mileage = scnr.nextInt();
System.out.println("Are you done? Yes or No");
quit1 = scnr.nextLine();
}
}
for(i=0; i<carInventory.length; i++)
System.out.println(carInventory[i].make + " " + carInventory[i].model + " " + carInventory[i].color + " " + carInventory[i].year + " " + carInventory[i].mileage);
try {
PrintWriter outputstream = new PrintWriter(fileName);
outputstream.println(carInventory[i].make + " " + carInventory[i].model + " " + carInventory[i].color + " " + carInventory[i].year + " " + carInventory[i].mileage);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am running into an issue now that as it completes the loop the first and second instance are combining and it is not allowing me to enter a string for Make each time. Also when I printed to a file it only printed one instance and not all of the instances. Any help is appreciated.
Because you aren't initializing the quit variable, and are using a do-while loop, the loop executes once without checking if quit = "quit". This causes the loop to appear to execute fine, but then crash on the second iteration.
If we examine the structure of how the loop executes:
1) Print "Car Model:"
2) Print "Car Make:"
3) Print "Car Color:"
4) Print "Car Year:"
5) Print "Car Mileage:"
6) Execute For loop
7) Evaluate whether quit == "quit"
8) Print "Car Model"
9) Etc...
When step #7 attempts to evaluate the equality, it is actually performing this comparison:
!null.equalsIgnoreCase("quit"));
Because above in the code, the variable quit was never initialized, and is still set to null. The two code snippets below are in essence equivalent:
// Initialization without assignment:
String quit;
// Explicit initialization to null:
String quitTwo = null;
// Output
print quit
// >> NullPointerException
print quitTwo
// >> NullPointerException
Your Automobile class is fine.
In your automobileInventory class, your are initializing static data member in a non-static method (Check the function where you are initializing the automobiles array).
You can simply initialize it where you are declaring it i.e.:
private static Automobile[] automobiles = new Automobile[ INVENTORY_SIZE ];
Another way is to initialize it in a static block i.e.:
private static Automobile[] automobiles;
static {
automobiles = new Automobile[ INVENTORY_SIZE ];
}
Another way is to initialize it in your function before your loop.
In your sentinel-controlled loop, you are checking exit condition on quit variable but you are not assigning it anything. You need to get value from user whether he/she intends to quit or not.
Here's an example:
String quit; // In your function; not a class member
do {
// ... Rest of your code ...
System.out.println("Do you want to quit [Yes/No]? ");
quit = scnr.nextLine();
}
while ( !quit.equalsIgnoreCase("yes") );
And, you need to take care of your array instance of automobiles that it is correctly being populated. You need to take care of its index that it remains valid.
String quit; // In your function; not a class member
int i = 0;
do {
// ... Rest of your code ...
if ( i < INVENTORY_SIZE ) {
automobiles[i] = new Automobile(make, model, color, year, mileage);
i++;
}
else {
// ... Display error message here that array is full ...
// ... You can then break this loop to exit if you want to ...
break;
}
System.out.println("Do you want to quit [Yes/No]? ");
quit = scnr.nextLine();
}
while ( !quit.equalsIgnoreCase("yes") );
Here's your working code: https://ideone.com/JqX9Y9
Some of the lines are commented for my own testing. You can easily correlate the changes with this answer and figure out yourself what is going on.
Best of luck!
Happy coding!
As #kushagra mentioned, you need to initialize your quit variable. It's currently null, hence the NullPointerException (trying to call a method that doesn't yet exist for your variable)
One tip regarding your quit variable though, I would change it to type boolean since all you need is a true/false. This way, you don't have to do any string comparisons. It would look something like this:
boolean quit = false;
...
do { /* loop stuff */ }
while(quit != true);
Then in your do loop, you can add logic to change your quit variable to true when your user is ready to quit.
Regarding your inventory, I wouldn't use an array if you don't have to; I would use a list (arrays can't change size, whereas lists can). Then instead of using your for loop (you're already looping with your do-while - makes it a little redundant), you can add a new automobile to your list where you currently have it commented out. It would look something like this:
private static List<Automobile> automobiles;
...
automobiles.add(new Automobile(make, model, Color, year, mileage));
UPDATE
Your code is pretty messy - make sure you're consistent with your tabbing/spacing/etc. You should also come up with a clean way of organizing your methods. For example, I like to keep all my getters and setters together with constructors right below the class properties. The bottom of the class is where I like to keep general class methods, overridden methods, etc.
One issue you have with your code is in your main(...); try not to loop within loops if you don't have to (obviously there are always exceptions, such as multidimensional arrays, traversing "grids", etc) - this can slow down execution quite a bit (check out Big O notation - this is a pretty good article: https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/). This will also help you keep track of when your loop closes.
Your file write only happens once because you're not looping (this is where consistent indentation/spacing may help you).
Couple more quick tips: whenever you reuse a value, make a variable for it. You did this a few times, but there were several instances where you could have used a variable (remember: method calls take time to run, so limiting redundant calls will speed up your program). Also, don't be afraid to override the toString() method in your classes - the automobiles class is actually a really good use case for it.
I tried not to give you all the answers, but I've rewritten your code a bit to help you get going:
import java.util.ArrayList;
import java.util.List;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
class Automobiles {
String color = "";
String make = "";
String mileage = "";
String model = "";
String year = "";
// -------------------- getters -------------------- //
public String getColor() { return color; }
public String getMake() { return make; }
public String getModel() { return model; }
public String getMileage() { return mileage; }
public String getYear() { return year; }
// -------------------- setters -------------------- //
public void setColor(String color) { this.color = color; }
public void setMake(String make) { this.make = make; }
public void setMileage(String mileage) { this.mileage = mileage; }
public void setModel(String model) { this.model = model; }
public void setYear(String year) { this.year = year; }
#Override
public String toString() {
return year + " " + model + " " + make;
}// end toString()
}// end class Automobiles
public class AutomobileInventory {
public static void main(String[] args) {
List<Automobiles> carInventory = new ArrayList<>();
String fileName = "out.txt";
boolean quit = false;
Scanner scnr = new Scanner(System.in);
do {
Automobiles car = new Automobiles();
System.out.println("Please Enter the year of the vehicle: ");
car.setYear(scnr.nextLine());
System.out.println("Please Enter the make of the vehicle: ");
car.setMake(scnr.nextLine());
System.out.println("Please Enter the model of the vehicle: ");
car.setModel(scnr.nextLine());
System.out.println("Please Enter the vehicle color: ");
car.setColor(scnr.nextLine());
System.out.println("Please Enter the vehicle's mileage: ");
car.setMileage(scnr.nextLine());
carInventory.add(car);
System.out.println("Are you done? Yes or No");
quit = "yes".equals(scnr.nextLine().trim().toLowerCase()) ? true : false;
} while(quit == false);// end do-while-loop
int numCars = carInventory.size();
for(int i = 0; i < numCars; i++) {
String currentCar = carInventory.get(i).toString();
System.out.println(currentCar);
try {
PrintWriter outputstream = new PrintWriter(fileName);
outputstream.println(currentCar);
} catch( FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}// end try-catch
}// end for-loop
}// end main(String[] args)
}// end class AutomobileInventory
public class Game {
private ArrayList<Player> players;
private ArrayList<Card> deck;
private ArrayList<Card> pool;
**private ArrayList<Capture> capture;**
private int currentPlayer;
private int playDirection;
int index;
int count = 0;
int passNo = 0;
Scanner input = new Scanner(System.in);
Scanner input2 = new Scanner(System.in);
Scanner input3 = new Scanner(System.in);
public Game()
{
deck = new ArrayList<Card>();
pool = new ArrayList<Card>();
capture = new ArrayList<Capture>();
for(int c=0; c<4; c++){
for(int i=0; i<13; i++){
deck.add(new Card(c,i));
}
Collections.shuffle(deck);
}
}
public Player play() {
Player player = getCurrentPlayer();
int pass = -1;
int option =0;
int count =0;
boolean play = false;
boolean check = true;
capture = new ArrayList<Capture>();
System.out.println();
System.out.println(player + ":" + player.getCards());
do{
System.out.println("Please select an option: ((1) Capture (2) Discard a card)");
option = input2.nextInt();
play=player.isPlayable();
switch(option)
{
case 1:
if(play == true){
System.out.print("HandCard:" + player.getCards());
System.out.print(" Choose a Number from 0 to " + (player.getCards().size()-1)+ " : ");
int num = input.nextInt();
player.getCards().remove(num);
//after prompting user for entering the cards they wanted
//the following sentence has following error
**capture.add(player.getCards().get(num));**
//"The method add(Capture) in the type ArrayList<Capture> is
//not applicable for the arguments (Card)"
System.out.print("How many card you want capture from pool: (Choose 1 number from 1 to " + pool.size()+ ")" + " : ");
option = input.nextInt();
System.out.println("Please choose your card in the pool:");
System.out.println("Pool");
for(int j=0; j<pool.size(); j++)
{
System.out.print("(" + j + ")" + pool.get(j) + " ");
}
for(int i=0; i<option;i++)
{
count = input.nextInt();
System.out.print(pool.get(count) + " ");
pool.remove(count);
//same problem as the above error
**capture.add(pool.get(count));**
}
System.out.print(player.getCards().get(num) + " is selected");
System.out.println();
System.out.println("=================================================");
check=false;
}
else
System.out.println("Invalid Capture, Please choose either (1) Capture or (2) Discard a Card");
break;
case 2:
if(play == true){
Card discard = player.cardDiscard();
System.out.println(discard + " has been added to pool");
pool.add(discard);
player.removeCard(discard);
check=false;
}
else
System.out.println("Invalid Capture Please choose either (1) Capture or (2) Discard a Card");
break;
default:
System.out.println("Invalid option choose");
}
}while(check);
if(pass==currentPlayer)
{
passNo++;
}
else{
passNo = 0;
}
if(player.getCards().size() == 0 ){
int i = 1;
int [] point = new int[players.size()+1];
point[0] = 100;
int lowest = 0;
System.out.println();
for(Player p : players){
System.out.println(p + ":" + p.getTotalScores() + " points");
point[i] = p.getTotalScores();
if(point[i] < point[i-1]){
lowest = point[i];
}
i++;
}
for(Player p:players){
if(p.getTotalScores()==lowest)
{
player = p;
}
}
return player;
}
goToNextPlayer();
System.out.println();
System.out.println("=========================================================================");
System.out.println("Pool");
for(int i=0; i<pool.size(); i++)
System.out.print("(" + i + ")" + pool.get(i) + " ");
return null;
}
//Capture Class
import java.util.ArrayList;
public abstract class Capture {
private static ArrayList<Capture> capture;
private static ArrayList<Card> card;
boolean result = false;
public Capture()
{
// leave bank
}
// this part is the functions that hv to implement in pair , run , combo class
public abstract boolean formCapture(ArrayList<Capture> c);
public abstract double getScore();
public abstract void showMessage();}
Sorry for the long post but my problem lies on the parts commented, the errors appear making me unable to add the player hand cards and pool cards into the ArrayList<Capture> Capture list, but this list cannot be removed as it is being used in another class to detect other features used by other subclass. How do I solve the error and add the arraylist capture into a new type array list?
**Edited, Capture class has been added but not complete yet
Make an Interface let's say CardAndCapture and your Card and Capture class should implement this interface. Now in your code, change this line
capture = new ArrayList();
into
capture = new ArrayList();
Now your code should compile and run. You are making Card and Capture siblings here. So, make sure to properly integrate with CardCapture interface.
If Capture has Card as instance variable like this:
public class Capture{
private Card card;
public Capture(Card card){
this.card = card;
}
...
}
Usage
capture.add(new Capture(player.getCards().get(num)));
capture.add(player.getCards().get(num));
In this line
player.getCards().get(num)
is returning a Card object reference.
But you decleared the Arraylist as
private ArrayList<Capture> capture;
So
capture.add();
this method can only take a Capture Object reference as parameter or any object reference that may have same parent as Capture. where as you are providing it a Card Object reference And I am assuming it Card does not have the same ancestor or implements from the same interface as Capture. That is why it is giving you that error.
Store object in a common list just if they have common usage. If they have common usage then partition this functionality into an interface and implement this interface by the classes intended to handle in the same manner. Create a generic list with this interface type and do method calls on the interfaces:
public interface ICommonUsage
{
public void foo();
public void bar();
}
public class Class1 implements ICommonUsage
{
//...
public void foo() {}
public void bar() {}
//...
}
public class Class2 implements ICommonUsage
{
//...
public void foo() {}
public void bar() {}
//...
}
public class Class3
{
//...
private List<ICommonUsage> commonUsedObjects;
public void commonUsage()
{
for ( ICommonUsage item : commonUsedObjects )
{
item.foo();
item.bar();
}
}
//...
}
If you want to add an object/interface to a generic list that is not conform with its class (it hasn't the ability to call the methods on it) the compiler log an error message.
I am creating a simple games score report generator program which takes input and turns it into a .txt file. It takes a name, a game name, an achievement score and minutes played and I want to be able to tally up the amount of games input, add up the achievement score and also add up the minutes (and convert to hours).
This is an example of how my output to .txt looks at the moment -
This is an example of how I would like an output to look -
How do I aggregate data that was input into the console and stored in an array to get results that I want?
PrintWriter writer = new PrintWriter(new FileOutputStream("Gaming Report Data", true));
writer.println("Player : " + gamerName);
writer.println();
writer.println("--------------------------------");
writer.println();
String[] report = gamerReport.split(":");
writer.println("Game: " + report[0] + ", score= " +report[1] + ", minutes played= " +report[2]);
writer.println();
writer.close();
Source code
package JavaProject;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
import java.nio.file.*;
public class JavaProject {
private static final int minutesPlayed = 0;
private static char[] input;
public static void main(String[] args) {
//variables
int hrs = minutesPlayed * 60;
int mins;
String gamerName, gamerReport = null;
int gameCount;
int errorCount;
//Main data storage arrays
String[] gameNames = new String[100];
int[] highScores = new int[100];
int[] minutesPlayed = new int [100];
#SuppressWarnings("resource")
Scanner Scan = new Scanner(System.in);
//formatting for output and input
System.out.println("////// Game Score Report Generator \\\\\\\\\\\\");
System.out.println(" ");
//User enters either their name or quit. Entering a name will move on to next part
for ( ; ; )
{
System.out.print("Enter your Name.");
System.out.println(" ");
gamerName = Scan.nextLine();
for(int b = 1; b < 99; b++ ) { //this is making the code loop 100 times
//user is given an example of input format
System.out.println(" ");
System.out.println("Input Gamer Information " + "Using Format --> Game : Achievement Score : Minutes Played");
System.out.println("FALSE DATA FORMAT WILL CAUSE ERROR");
System.out.println(" ");
//another data input guide which is just above where data input is in console
System.out.println("Game : Achievement Score : Minutes Played");
gamerReport = Scan.nextLine();
String[] splitUpReport; // an array of string
if (gamerReport.equalsIgnoreCase("quit")) {
System.out.println("You have quit!");
return;
}
splitUpReport = gamerReport.split(":");
int i = 0;
//copy data from split text into main data storage arrays
gameNames[i] = splitUpReport[0];
highScores[i] = Integer.parseInt(splitUpReport[1].trim() );
minutesPlayed[i] = Integer.parseInt(splitUpReport[2].trim());
//output to file using a PrintWriter using a FileOutPutStream with append set to true within the printwriter constructor
//
try
{
PrintWriter writer = new PrintWriter(new FileOutputStream("Gaming Report Data", true));
writer.println("Player : " + gamerName);
writer.println();
writer.println("--------------------------------");
writer.println();
String[] report = gamerReport.split(":");
writer.println("Game: " + report[0] + ", score= " +report[1] + ", minutes played= " +report[2]);
//writer.println("Games Played : " + minutesPlayed);
writer.close();
} catch (IOException e)
{
System.err.println("You have made an error with data input");
}
}
System.out.println("You have quit!");
}
}
public static char[] getInput() {
return input;
}
public static void setInput(char[] input) {
JavaProject.input = input;
}
}
So I am assuming that your array data structure looks like this:
Object[] report = new Object[] {new String(), new Integer(), new Integer()}
where the first entry is the game name, the second is the score, and the third is the time played.
I would suggest that you bundle this data into its own object instead of tracking every 3 positions in an array. Try:
public class Game
{
private String name; public String getName() { return name; }
private int score; public int getScore() { return score; }
private int minutesPlayed; public int getMinutesPlayed() { return minutesPlayed; }
public Game(String name, int score, int minutesPlayed)
{
this.name = name;
this.score = score;
this.minutesPlayed = minutesPlayed
}
#Override
public String toString()
{
return "Game: " + name + ", score= " + score + ", minutes played= " + minutesPlayed);
}
}
You can then use this object to represent game data and hold and array of these objects like this:
Game[] games = new Game[]{
new Game("Game 1", 52, 89),
new Game("Game 2", 57, 58),
new Game("Game 3", 67, 86)
};
This array allows us to access each game as a single entity; for example games[0] would get the reference to the 1st game object in the array. These games can have their data accessed by calling the "getters" for the 3 fields contained in the Game object. games[0].getName() would return the name for the first Game object; likewise, games[0].getMinutesPlayed() would return the minutes played for the first game.
Since we overrode the toString method offered to all classes from java's object class to output a string of the data desired in the way your first file I/O was structured. You can call writer.println(games[i]) where i is and index in your array of games to write the data for a individual game.
To concatenate this data into the output you desired. We can do the following:
// get the number of games played
int gamesPlayed = games.length;
// get the raw data on score and time
int totalScore = 0;
int totalMinutesPlayed = 0;
for(int i = 0; i < games.length; i++)
{
totalScore += games[i].getScore();
totalMinutesPlayed += games[i].getMinutesPlayed;
}
// compile the output string
String output = "Games Played: " + gamesPlayed
+ "\n\nTotal Achievement: " + totalScore
+ "\n\nTotal Time: " + totalMinutesPlayed
+ " (" + totalMinutesPlayed / 60
+ " hours and " + totalMinutesPlayed % 60
+ " minutes).";
// write the string to the file
writer.println(output);
Suggestion:
Create a model of the data as a new simple class:
public class GameReportModel{
String gamename = null;
String username = null;
int score = 0;
int minutesplayed = 0;
}
Now you can use an ArrayList of this model to store data before generate the report:
//Declare
ArrayList<GameReportModel> myArray = new ArrayList<GameReportModel>();
//Populate (example) for each input
GameReportModel myobj = new GameReportModel();
myobj.gamename = "My Game"; //<<from input source
myobj.username = "John"; //<<from input source
myobj.score = 20; //<<from input source
myobj.minutesplayed = 45; //<<from input source
myArray.add(myobj);
// Iterate
for(GameReportModel line : myArray){
writer.println("Player : " + line.username);
... and sumarize for each Player
}
Now you can build some scripts to sort by name, game. This method turn it easy but consume more virtual machine resources (memory and steps). But you can manipulate data with another perspective.
Add and remove Array elements easy.
I created a method that returns a row of arrays via user input. I managed to display the set of inputted number on the same class using System.out.println by assigning each value in userDigits.
My question is, how can I pass the same value in another class?
public class LottoTicket extends Ticket {
public int NUM_DIGITS = 5;
public int[] userDigits = new int[NUM_DIGITS];
#Override
public void buyTicket() {
Scanner input = new Scanner(System.in);
int number = 0;
double amount = 0;
System.out.println("-------=======LOTTO TICKET SCREEN=======--------");
System.out.println("");
System.out.println("There are three Types (Prima, Ambo and Terro)");
System.out.print("Please select one (P, A, T): ");
String lotteryOption = input.next();
switch (lotteryOption) {
case "P": {
break;
}
case "A": {
break;
}
case "T": {
amount = getAmount(amount);
getUserData(userDigits);
int ticketSold;
ticketSold = +1;
int tik = ticketSold +1;
System.out.println(amount);
System.out.println("Your numbers are: " + userDigits[0] + " "
+ userDigits[1] + " " + userDigits[2] + " " + userDigits[3]
+ " " + userDigits[4] + " ");
System.out.println("Ticket/s Sold: " + tik);
System.out.println("Thank you for playing");
Ticket.pressAnyKeyToContinue();
LotteryApplication.loginScreen();
break;
}
default: {
System.out.println("Invalid Input. Please try again.");
System.out.println("");
buyTicket();
break;
}
}
}
#Override
public double getAmount(double amount) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter amount of money: ");
amount = input.nextDouble();
//input.close();
return amount;
}
#Override
public int getUserData(int[] userInput) {
Scanner input = new Scanner(System.in);
System.out.print("Choose a number from 1 to 90: ");
userDigits[0] = input.nextInt();
System.out.print("Choose a number from 1 to 90: ");
userDigits[1] = input.nextInt();
System.out.print("Choose a number from 1 to 90: ");
userDigits[2] = input.nextInt();
System.out.print("Choose a number from 1 to 90: ");
userDigits[3] = input.nextInt();
System.out.print("Choose a number from 1 to 90: ");
userDigits[4] = input.nextInt();
//key.close();
//Returns last value of array
return userDigits[4];
}
//public int userDigits[];
public static void printTicket(){
// System.out.println(getUserData.userDigits[4]);
// for (int i = 0; i < array.length)
}
}
Well, in this case, since you defined userDigits as public, you can do it easily - it is accessible to any class that has a visibility to your instance of LottoTicket. With the current setup you could do something like this:
// you need to instantiate LottoTicket somewhere in your app
LottoTicket ticket = new LottoTicket();
// get the input from user
ticket.buyTicket();
// at this point you can access the numbers and pass them to some other method like this
checkNumbers(ticket.userDigits);
The example posted above needs you to provide a method checkNumbers that has, for example, the following signature:
public void checkNumbers(int[] numbers) {
// the comparison code goes here...
Also, this is somewhat unrelated to your question, but I'd like to point out two issues with your current code:
defining class fields as public is done rather rarely, more common approach is to define these as private and provide methods for getting/setting the field values; this restricts the operation on these fields to only those you allow - having public field allows anyone who has a visibility to that field to perform basically any operations, which is usually not what you want
you call buyTicket() from default in case user didn't select valid lottery type; in extreme cases this could lead to StackOverflowError - better approach would be to use a loop that keeps asking user for input until a valid one is provided
Hope this helps at least a bit.
You can easily pass input array to method of another class arguments.
class PassValue{
public static void display(int[] elements){
Anotherclass obj= new Anotherclass();
obj.display2(elements);
}
}
class Anotherclass{
public void display2(int[] values){
do whatever you want
}
}
This is my Code that I have so far:
import java.util.*;
public class VoteRecorder
{
// Variables and instance variables
public static String nameCandidatePresident1;
public static String nameCandidatePresident2;
public static String nameCandidateVicePresident1;
public static String nameCandidateVicePresident2;
public static int votesCandidatePresident1;
public static int votesCandidatePresident2;
public static int votesCandidateVicePresident1;
public static int votesCandidateVicePresident2;
private int myVoteForPresident;
private int myVoteForVicePresident;
public VoteRecorder()
{
nameCandidatePresident1 = "null";
nameCandidatePresident2 = "null";
nameCandidateVicePresident1 = "null";
nameCandidateVicePresident2 = "null";
votesCandidatePresident1 = 0;
votesCandidatePresident2 = 0;
votesCandidateVicePresident1 = 0;
votesCandidateVicePresident2 = 0;
myVoteForPresident = 0;
myVoteForVicePresident = 0;
}
public void setCandidatesPresident(String name1, String name2)
{
nameCandidatePresident1 = name1;
nameCandidatePresident2 = name2;
}
public void setCandidatesVicePresident(String name1, String name2)
{
nameCandidateVicePresident1 = name1;
nameCandidateVicePresident2 = name2;
}
public static void resetVotes()
{
votesCandidatePresident1 = 0;
votesCandidatePresident2 = 0;
votesCandidateVicePresident1 = 0;
votesCandidateVicePresident2 = 0;
}
public static String getCurrentVotePresident()
{
return nameCandidatePresident1 + ":" + votesCandidatePresident1 + "\n" +
nameCandidatePresident2 + ":" + votesCandidatePresident2;
}
public static String getCurrentVoteVicePresident()
{
return nameCandidateVicePresident1 + ":" + votesCandidateVicePresident1 + "\n" +
nameCandidateVicePresident2 + ":" + votesCandidateVicePresident2;
}
public void getAndConfirmVotes()
{
}
private String getVotes()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("please vote for a President or vice president " + nameCandidatePresident1 + ", " + nameCandidatePresident2 + ", " + nameCandidateVicePresident1
+ " or " + nameCandidateVicePresident2);
String presidentVote = keyboard.nextLine();
if (presidentVote.equalsIgnoreCase(nameCandidatePresident1))
return nameCandidatePresident1;
if(presidentVote.equalsIgnoreCase(nameCandidatePresident2))
return nameCandidatePresident1;
System.out.println("please vote for a Vice president " + nameCandidateVicePresident1 + " or" + nameCandidateVicePresident2);
String vicePresidentVote = keyboard.nextLine();
if(vicePresidentVote.equalsIgnoreCase(nameCandidateVicePresident1))
return nameCandidateVicePresident1;
if(vicePresidentVote.equalsIgnoreCase(nameCandidateVicePresident2))
return nameCandidateVicePresident2;
else
return "not a valid vote";
}
private boolean confirmVotes()
{
System.out.println("Your vote for President is:");
System.out.println("your vote for Vice President is:");
System.out.println("Is this correct? Yes or No?");
Scanner keyboard = new Scanner(System.in);
String answer = keyboard.nextLine();
if (answer.equalsIgnoreCase("Yes"))
return true;
else
return false;
}
private void recordVote()
{
puscode: If confirmVotes returns true, take the nameCandidate, and ++ to votesCandidate of the same type
Copy this If statement four times, one for each of the candidates, 2 president and 2 vp.
Else or If confirmvotes returns false, put output saying that the votes were not confirmed.
}
}
Say i had all this code, lets look at the method getVotes() and confrimVotes(), in getVotes() the user picks a candidate and than that candidate is returned. How would i get that return statement to show up else where in other methods? like in confirmVote() i want to do this
System.out.println("Your vote for President is: (PresidentialCandidate return statement");
But how can i do that?
This is not a direct answer to your question, but I think your code could be made a lot simpler by harnessing some of the power of object-oriented programming.
You are storing multiple types of information about 4 candidates for different positions as separate variables, and it's making your class very unwieldy.
A (in my opinion) better approach would be to have e.g. a Candidate class to store information about a single candidate, and then your classes could look as follows:
class Candidate {
String Name;
int votes;
}
class VoteRecorder {
Candidate[] presidents;
Candidate[] vicePresidents;
Candidate myVoteForPresident; //Or even make these both ints.
Candidate myVoteForVicePresident;
}
The classes can be further refined, but this will be a start. Any time you see multiple pieces of information that describe the same entity being repeated multiple times, it's a good indication that you could simplify your life by adding a class to represent them together instead.
Edit (to answer question specifically):
If you want to do effectively the following:
System.out.println("Your vote for President is: (PresidentialCandidate return statement");
You can write something like this:
String voteResult = getVotes();
System.out.println("Your vote for President is: " + voteResult);
Or in one line:
System.out.println("Your vote for President is: " + getVotes());
Each time you run this code though, it will prompt the user for input. If you want to save the result until next time as well, you will have to save it to an attribute, e.g. by having a string in your class, and assigning the value to it first. Then just use that later instead of the local variable voteResult.