In the program I'm creating, the user will input values to create an array of videos. Each video contains several data fields (number, title, publisher, duration & date). However what I am currently trying to acheive is to let the user choose a particular video in the array they just created, select the data field they wish to rename, rename the value and then set the renamed value as the new value. Here is my code for adding videos to an array:
public Library createLibrary()
{
Library video = new Library();
java.util.Scanner scannerObject =new java.util.Scanner(System.in);
for (int i = 0; i < videos.length; i++)
{
//User enters values into set methods within the 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 video;
}
And here is the basic concept for my select and replace function for those who can't figure out what I mean:
public void replaceVideo(Library[] videos, String replaceTo, String replaceWith)
{
for (int i = 0; i < videos.length; i++)
if (videos[i].equals(replaceTo)) {
videos[i]= replaceWith;
}
}
Simpler solutions will be appreciated. Thanks.
Try comparing replaceTo to the name of the video (or whatever replaceTo is supposed to match):
if (videos[i].getName().equals(replaceTo)) {
I can't see your replace ever working, since it appears that you are comparing a Library type and a String type with .equals().
If you use one of the Collection classes instead of an array, the replace method changes to
public void replaceVideo(Vector<Library> videos, Library current, Library newCopy)
{
Collections.replaceAll(videos, current, newCopy);
}
I used Vector, but you could use a Set, List, etc. as needed.
For your code to work, you need to override the Library.equals method to compare strings only. Otherwise, you can compare the video title, for one sample, against the parameter replaceTo.
Certainly, it is OOP elegant to override the equals method. Try my suggestion and Thomas'
Good luck.
Related
I have the following method in a program of mine that allows a user to enter a unique ID that is associated with a laptop in an ArrayList.
The desired output is as follows:
If the ID entered by the user matches an ID in the ArrayList, the laptop and its specifications will print out.
If the ID does not match, it will print out "Invalid ID".
I am very close to achieving this; however I can only figure out how to get it to print whether or not it matches for each laptop in the list. So for example, if the ID entered by the user matches one of three laptops in the list it will print as follows:
Acer Predator Helios 300 CPU: Intel i7-9750h GPU: NVIDIA GTX1660ti Memory: 16GB ID: 1234567
Invalid ID.
Invalid ID.
So my question is: how do I get it to print ONLY the single match or "Invalid ID" while still being able to loop through the entire list to check for a match? Not necessarily asking you to spoon feed me the fix, but at least help point me in the right direction or help with the logic. I thank you in advance for any help!
My method is as follows:
private static void findLaptop(ArrayList arr) {
//Prompt user to input an ID.
System.out.println("Input ID: ");
System.out.println();
//Scan for user input.
Scanner keyboard = new Scanner(System.in);
int inputId = keyboard.nextInt();
//Loop through ArrayList and check for a match.
for(int i=0; i<arr.size(); i++) {
//If entered ID matches, print laptop information.
if(inputId == ((Laptops) arr.get(i)).getId()) {
System.out.println(((Laptops)arr.get(i)).getModel() + " CPU: " + ((Laptops)arr.get(i)).getCpu() + " GPU: " +
((Laptops)arr.get(i)).getGpu() + " Memory: " + ((Laptops)arr.get(i)).getMemory() + "GB ID: " +
((Laptops)arr.get(i)).getId());
}
//If entered ID does not match, print invalid ID.
else if(inputId != ((Laptops) arr.get(i)).getId()) {
System.out.println("Invalid ID.");
}
}
}
Use below code:
//Create a boolean
boolean found= false;
for(int i=0; i<arr.size(); i++) {
//If entered ID matches, print laptop information.
if(inputId == ((Laptops) arr.get(i)).getId()) {
System.out.println(((Laptops)arr.get(i)).getModel() + " CPU: " + ((Laptops)arr.get(i)).getCpu() + " GPU: " +
((Laptops)arr.get(i)).getGpu() + " Memory: " + ((Laptops)arr.get(i)).getMemory() + "GB ID: " +
((Laptops)arr.get(i)).getId());
//set boolean true and break
found = true;
break;
}
}
//Out side the look check If entered ID does not match, print invalid ID.
if(!found) {
System.out.println("Invalid ID.");
}
You can do this using a return statement that is used after printing a match
for(int i=0; i<arr.size(); i++) {
//If entered ID matches, print laptop information.
if(inputId == (arr.get(i)).getId()) {
System.out.println((arr.get(i)).getModel() + " CPU: " + (arr.get(i)).getCpu() + " GPU: " +
(arr.get(i)).getGpu() + " Memory: " + (arr.get(i)).getMemory() + "GB ID: " +
(arr.get(i)).getId());
return;
}
}
// outside loop
System.out.println("Invalid ID.");
edit
If you have you ArrayList set up properly as ArrayList<Laptop> then you would not need all those crazy casts.
edit2
If you a foreach loop it would be even cleaner
for (Laptop lt : arr) {
if (iputId == lt.getId()) // etc
Supposing you have a class called Laptop as follows:
public class Laptop {
private String id;
private String manufacturer;
// other fields
// getters and setters
}
You can find matches with an id using Java 8 Streams:
List<Laptop> laptops = ...
String idToSearch = "something";
Optional<Laptop> result = laptops.stream() // convert into stream for easier handling
.filter(l -> l.getId().equals(idToSearch)) // find only laptops with a matching id
.findFirst(); // find the first one, if present
The variable result is an Optional<Laptop>, meaning it may or may not contain a Laptop value. You can consume this result as follows:
Laptop laptop = result.get(); // throws an exception if no value present, not reccomended
Laptop laptop = result.orElse(null); // returns null if no value present
result.ifPresent(laptop -> {
doSomething(laptop); // this function is only called if a value is present
})
I am wondering what the easiest way to write the output (last line of non-commented code below) to a .rtf file so that I can format some aspects with italics as well as keep a continuous, copy and paste-able, list of all my citations. Is there a way to do what I want that is simple? I am a beginner at Java and don't want anything too complicated to deal with.
/* (c) Tyler Holley January, 2018
* CitationGenerator Version 0.2
*
* User inputs academic source information and gets a proper citation back ready for copy and pasting into a Works Cited page.
*/
import java.util.Scanner;
class CitationGenerator {
public static String bookFormat(String author, String title, String publisher, int pubDate) {
//
String bFormat = author + ". " + title + ", " + publisher + ", " + pubDate + ".";
return bFormat;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String error1 = "ERROR: INVALID INPUT."; // Catchall error
String errorN = "ERROR: No other formats are currently supported in this version."; // Filler error while WIP
System.out.println("Welcome to CitationGenerator v0.1!");
System.out.print("What format is your citation in? MLA/APA/Chicago: "); // Add APA/Chicago support
String format = in.next();
if (format.equalsIgnoreCase("MLA")) { // equalsIgnoreCase ignores case inputted so MLA, mLa, mla, etc. are all valid
System.out.print("\nIs your source a book, website, or other? ");
String sourceType = in.next();
// Try and figure out how to clear the console after the user inputs sourceType
if (sourceType.equalsIgnoreCase("book")) {
System.out.print("\nAuthor's First Name: ");
String fName = in.next();
System.out.print("Author's Last Name: ");
String lName = in.next();
in.nextLine();
System.out.print("\nBook Title: ");
String title = in.nextLine();
System.out.print("\nPublisher Name: ");
String publisher = in.nextLine();
System.out.print("\nPublication Date: ");
int pubDate = in.nextInt();
String author = lName + ", " + fName; // Converts fName and lName to one concatonated String
System.out.println("\n\nHere is your citation! Don't forget to italicize the title!\n");
// Try to automatically italicize text when converting program to a .rtf
System.out.println(bookFormat(author, title, publisher, pubDate));
// GOAL: Alternate to the println below :
//System.out.println("\n\nYour citation is ready, would you like to save it to a/the .rtf document? y/n");
// This would branch into an if/else statement to print either to a document or continue to terminal output.
}
}
}
Pretty similar to writing to any file:
DataOutputStream dos;
File file = new File("\\your\\file\\path\\file.rtf");
try {
dos = new DataOutputStream(new FileOutputStream(file));
dos.writeBytes(bookFormat(author, title, publisher, pubDate));
dos.close();
catch( //IOexception or similar etc
Output:
surname, firstname. booktitle, bookpublisher, 1234.
Here are some lines from a file and I'm not sure how to parse it to extract 4 pieces of information.
11::American President, The (1995)::Comedy|Drama|Romance
12::Dracula: Dead and Loving It (1995)::Comedy|Horror
13::Balto (1995)::Animation|Children's
14::Nixon (1995)::Drama
I would like to get the number, title, release date and genre.
Genre has multiple genres so I would like to save each one in a variable as well.
I'm using the .split("::|\\|"); method to parse it but I'm not able to parse out the release date.
Can anyone help me!
The easiest would be matching by regex, something like this
String x = "11::Title (2016)::Category";
Pattern p = Pattern.compile("^([0-9]+)::([a-zA-Z ]+)\\(([0-9]{4})\\)::([a-zA-Z]+)$");
Matcher m = p.matcher(x);
if (m.find()) {
System.out.println("Number: " + m.group(1) + " Title: " + m.group(2) + " Year: " + m.group(3) + " Categories: " + m.group(4));
}
(please don't nail me on the exact syntax, just out of my head)
Then first capture will be the number, the second will be the name, the third is the year and the fourth is the set of categories, which you may then split by '|'.
You may need to adjust the valid characters for title and categories, but you should get the idea.
If you have multiple lines, split them into an ArrayList first and treat each one separately in a loop.
Try this
String[] s = {
"11::American President, The (1995)::Comedy|Drama|Romance",
"12::Dracula: Dead and Loving It (1995)::Comedy|Horror",
"13::Balto (1995)::Animation|Children's",
"14::Nixon (1995)::Drama",
};
for (String e : s) {
String[] infos = e.split("::|\\s*\\(|\\)::");
String number = infos[0];
String title = infos[1];
String releaseDate = infos[2];
String[] genres = infos[3].split("\\|");
System.out.printf("number=%s title=%s releaseDate=%s genres=%s%n",
number, title, releaseDate, Arrays.toString(genres));
}
output
number=11 title=American President, The releaseDate=1995 genres=[Comedy, Drama, Romance]
number=12 title=Dracula: Dead and Loving It releaseDate=1995 genres=[Comedy, Horror]
number=13 title=Balto releaseDate=1995 genres=[Animation, Children's]
number=14 title=Nixon releaseDate=1995 genres=[Drama]
I'm trying to read separate names and instruments up until the total number of bandmembers(asked earlier in the program) is reached. The program reads the amount, and reads the first name. However after that it fails in that it only reads the first name, it does not print any name or instrument after.
The while loop below is the most likely source of the problem:
i = counter
while(i <= bandMembers)
{
System.out.println("What is band member " + i + "'s name?");
kb.nextLine();
String bName = kb.nextLine();
System.out.println("What instrument does " + bName + " play?");
kb.nextLine();
String bNamePlay = kb1.nextLine();
list = list + i + ":" + " " + bName + " - " + bNamePlay+ "\n";
i++;
}
This is what it prints if I entered the first name as bName1:
Band Members
--------------
1: bName1 -
2: -
3: -
Any help appreciated, thanks.
Use BufferedReader instead.This will fix your problem.:-
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
i=counter;
while(i<=bandMembers){
System.out.println("Enter band member "+i+" name:-");
String bName=br.readLine();
System.out.println("What instrument does "+bName+" play?");
String bNamePlay=br.readLine();
list = list + i + ":" + " " + bName + " - " + bNamePlay+ "\n";
i++;
}
You should be using
String bName = kb.next();
Under the assumption that you are using a Scanner.
When you call nextLine() it reads the remainder of the same line and does not wait for input.
I don't have enough rep to comment on the issue you're having:
I was using kb.next at first but it read each word separated by a space as the next name. For example I would input "Jimmy loose hands" and it would prompt for Jimmy's instrument correctly, but it would then ask for band member 2's name and "what instrument does loose play?" simultaneously. So it took the second word as the next name.
What you may want to do is remove the "kb.nextLine();" before "String bName = kb.nextLine();"
I don't have an IDE open to confirm it, but that may be the reason that it is taking the second word/string entered as the name.
I need some help writing a program
Using this code I am able to enter in a track name, artist, etc.
I have a problem that I cannot now show this information in JOptionPane to display all of my info
import java.util.Scanner;
import javax.swing.JOptionPane;
public class TestTrack
{
public static void main(String[] args)
{
Scanner myScan = new Scanner(System.in);
System.out.println("Track name");
String name = myScan.nextLine();
System.out.println("Artist");
String Artist = myScan.nextLine();
System.out.println("Track length seconds");
String seconds = myScan.nextLine();
System.out.println("Album");
String Album = myScan.nextLine();
JOptionPane.showMessageDialog(null,"Trackinfo:")
}
}
So I guess I would want the pop out window to say
Track Name: "blank"
Artist: blank
Another question I have is how to ask this question multiple times by using "while" and asking if I would like to add another track
Sorry if I am using any terminology incorrectly I just started to learn Java
This line: JOptionPane.showMessageDialog(null,"Trackinfo:")
Contains what the pop-up window will contain. You pass in what you want its contents to be as the 2nd parameter, which is currently "Trackinfo".
To incorporate a while loop, you'll have to have a loop control variable, or a condition that will break the loop. In my example I used a string. My example uses a while loop that will continue as long as the string is not equal to "quit".
String test = "";
while( ! test.equals("quit") ) {
//use Scanner to get the next value the user enters
//ask for track info
//display that info in a message box
}
To obtain this:
Note: the texts of the OK and Cancel buttons are localized, if your computer is set to US locale you doesn't see 'Annuler"... ;-)
code this:
int answer = 0;
do {
/*----------------------------------------------------------------------------
Here you put the code which set the variables name, artist, seconds... (1)
----------------------------------------------------------------------------*/
final String title = "Track info";
final String message =
"<html><table>" +
"<tr><td>Track name" + "</td><td>" + name + "</td></tr>" +
"<tr><td>Artist" + "</td><td>" + artist + "</td></tr>" +
"<tr><td>Track length seconds</td><td>" + seconds + "</td></tr>" +
"<tr><td>Album" + "</td><td>" + album + "</td></tr>" +
"</table>";
answer =
JOptionPane.showConfirmDialog(
null, message, title, JOptionPane.OK_CANCEL_OPTION );
} while( answer == JOptionPane.OK_OPTION );
(1) You may choose Scanner or GUI whith JOptionPane.showInputDialog()
JOptionPane.showMessageDialog(null,"Trackinfo:" + "\nArtist: " + Artist + "\nseconds: " + seconds + "\nAlbum: " + Album)
Each '\n' means a new line. for doing this multiple times, you should place your code in a while loop, something like this:
while(!(Artist == "end")) {
//your code
}
Use myScan.next() instead of myScan.nextLine()
To output the information into the Message Dialog, use
String trackInfo = "Track Name: " + name + " | Artist : " +artist+ " | Track Length: " + seconds + " | Album: " + album;
JOptionPane.showMessageDialog(null, trackInfo, "Trackinfo", JOptionPane.INFORMATION_MESSAGE);