Sorting a text file in Java per line [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last month.
Improve this question
I'm a newbie in Java and I have a file where every first line is the title of every second. For example the text file looks like this:
John Holm
blue
Anna Karina
orange
etc...
where every first line is the name of a person and every second is their favourite colour. Now I would like to use the information to for example find what is for example John Holm's favourite colour or change his favourite colour to green instead. How do I best access the data?
I tried with scanner to see all the lines where blue reoccurs, but I cannot get the code to write the previous line.
Should I split the text file into a table with name and favColour as columns or is there a way to assign the previous line to the next line as a name in Java? I also thought of splitting the file every second line. However, I am unsure which solution would be most efficient. Would be very thankful for some insights!

I think a solution would be to create an object containing the properties of your characters (their name and their favourite colour).
So, you can create a class named like how you want to name your object (let's call it Person), and set the name and the favourite colour as attribute of your Person object:
public class Person {
private String name;
private String favColour;
public Person(String name, String favColour) { // Constructor of your object
this.name = name; // Setting name
this.favColour = favColour; // Setting favourite colour
}
}
Now, create a main method to read your file, store the values into two lists, one containing the names, the other the colours, and then creating as many Person objects as you need:
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("src/wherever you stored it"); // Enter the file path as a String here
Scanner scanner = new Scanner(file); // Create a scanner that will read your file
List<String> names = new ArrayList<>(); // List that will contain the names read from the scanner
List<String> colours = new ArrayList<>(); // By the way don't forget to import *java.util.List* and *java.util.ArrayList* if your IDE doesn't do it automatically
int index = 0; // The index that'll know whether you store a name or a colour
try {
while(scanner.hasNext()) { // While the scanner still reads something from the file
if(index%2==0) { // If the index is even
names.add(scanner.next()); // Add the line to the names list
index++;
} else {
colours.add(scanner.next()); // Else add it to the colours list
index++;
}
}
} catch (Exception e) { // Don't forget to import *java.io.IOException*
System.err.println("Error: " + e.getMessage()); // You can write a custom message that will appear in your console if there's an error, e.g. if the program can't find your file
}
scanner.close(); // Close your scanner
// Now you can create a new Person object
Person p1 = new Person(names.get(0), colours.get(0)); // Create a Person object called p1, with the first element (index 0) of names and colours lists as attributes
System.out.println(p1); // Print your Person
}
}
Almost done, the last line must print some weird string. If you want to print your Person properly, you have to override the toString() method of your object:
// In the Person class:
#Override
public String toString() {
return "Name: " + this.name + "\nFavourite colour: " + this.favColour;
}
Now try again and you'll see the console prints properly what you want to see.
In the case of the example you gave, your console should print:
Name: John Holm
Favourite colour: blue
You can create as many Person objects as you want, and maybe store them into a list as well.
To make this simpler, you can create a function in your Person class:
public static Person newPerson(int i, List<String> names, List<String> colours) {
return new Person(names.get(i), colours.get(i));
}
And you can call it in your main:
Person p2 = Person.newPerson(1, names, colours);
You can now create a method that will create new Person objects from this function, and store them into a list or whatever you want.
To set a value, you'll have to create setters in your Person class, in order to modify the private characteristics of your Person from outside the Person class:
public void setName(String name) {
this.name = name;
}
You can do the same with the colour:
public void setFavouriteColour(String colour) {
this.favColour = colour;
}
And now, you can call these methods from your main:
p1.setName("John Doe");
p1.setFavouriteColour("green");
You can also create a method to combine both setters:
public void setPerson(String name, String colour) {
this.setName(name);
this.setFavouriteColour(colour);
}
By the way if you need these values at some point, you can also create a getter along with your setter:
public String getName() {
return this.name;
}
Feel free to ask anything you didn't understand or think is wrong :)

Related

Problem with comparing a value to a specific object of an ArrayList Java

I have the class Student with a constructor that sets the values int s_code, String name and int age.
When I create an object of the class Student I pass it into an ArrayList AllStudents.
My problem is that I want the user to enter an Id and check if there is that Id in the ArrayList. If its not let him add a new student else tell him to try again.
I tried to loop through the ArrayList with for and inside of it
I have an if statement with .contains and if it is true I have a simple println("Good") just to test it.
When I run my program though it skips it.
Here is my code:
static ArrayList<Student> AllStudents = new ArrayList<Student>();
static void InitStudents() //this is a method that creates some students when I call it in main.
{
AllStudents.add(new Student(1,"James",15));
AllStudents.add(new Student(2,"John",16));
AllStudents.add(new Student(3,"Rose",15));
}
System.out.println("Enter the ID of the student you want to add.");
Scanner get_new_code = new Scanner(System.in);
int s_code = get_new_code.nextInt();
for(Student code : AllStudents)
{
if (AllStudents.contains(s_code)) //I think that I have to include age and name for it to work.
{
System.out.println("Good");
}
}
By the way sorry if I didn't explain something or I did something completely wrong I'm new to Java.
That advanced loop is not helping you in the way you implemented it.
for(Student code : AllStudents){ //"code" is one element out of the list
if (AllStudents.contains(s_code)){ //here you are checking the whole list
System.out.println("Good");
}
}
This might be what you are looking for:
for(Student code : AllStudents){
if(code.getSCode() == s_code){ //here the one element named "code",
//out of the list, will be checked
System.out.println("Good");
}
}
A getter method (this one is called for example getSCode()) will help you here, to ask for every attribute of a student object. It will return the s_code of the object you are looking at.
EDIT AS EXAMPLE:
public class Student{
int s_code;
String name;
int age;
public Student(int code, String name, int age){
this.s_code = code;
this.name = name;
this.age = age;
}
public int getSCode(){
return s_code;
}
public int setSCode(int newSCode){
this.s_code = newSCode;
}
}
With the getter and setter you can ask for data of an object or you can set the data.
AllStudents contains students and s_code is an int.
You can search by id mapping it first. Assuming the code is in a field called Id.
allStudents.stream().map(s -> Student::getId).collect(Collectors.toList()).contains(s_code);

How to Create Objects Using Records in a Text File (Java)

I'm working on a program for my Java class where I'm using a file of objects (clothing items) that represents inventory for a store. Each Retail_Item has four attributes: int itemNumber, String description, int numInInventory, and double price.
What I'm trying to figure out is how to read in each line from the file and turn each line into an object. My first thought was to create a while loop with vars like currentItemNumber, currentDescription, etc. So I tried this:
while (file.hasNextLine()) {
currentItemNumber = file.nextInt();
currentDescription = file.next
} // end while
But I got stuck there because every other time I've read in a String to a Scanner, I've always used nextLine. Can't use that here though, because each line contains multiple attributes of the object, not a String within a line. Is there a way to do this in the structure I'm trying to use, or should I be doing this a different way? I know I've seen and done some things where I parsed a String into separate pieces which I've seen people refer to as "tokens." Would people recommend reading each line in and then parsing it into separate tokens, then assigning each token to its appropriate attribute? Then I guess I'd have to cast those tokens into the appropriate object, since I think reading the whole line in and then parsing it would make each piece a String.
Here's a sample of what's in the text file (which can't be changed in any way, per the professor's instructions):
1000 Pants 10 19.99
2000 Jeans 2 25.95
3000 Shirt 12 12.50
Thanks in advance for your sage wisdom if you've got it.
The following code fulfills your requirement as stated in your question, namely how to create an instance of class RetailItem from a line of text from your text file. I presume it uses things that you may not have learned yet, like class Paths and try-with-resources. This is just used to scan through your file.
First, class RetailItem contains the members you described in your question. Next, I wrote a constructor for class RetailItem that creates a new instance and initializes the instance members. Then I wrote a toString() method that displays the contents of a RetailItem object in "human readable" form. Finally a main() method that reads your text file (which I named "clothes.txt"), line by line - using a Scanner. For each line read, the code splits it using a delimiter which consists of at least one whitespace character. (I presume you haven't yet learned about regular expressions in java.) Then I convert the elements of the String array returned by method split() into appropriate data types that are required by the RetailItem constructor. Then I call the constructor, thus creating an instance of class RetailItem (as you requested) and I print the created instance.
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Scanner;
public class RetailItem {
private static final int FIELDS = 4;
private int itemNumber;
private String description;
private int numInInventory;
private double price;
public RetailItem(int itemNumber, String description, int numInInventory, double price) {
this.itemNumber = itemNumber;
this.description = description;
this.numInInventory = numInInventory;
this.price = price;
}
#Override // java.lang.Object
public String toString() {
return String.format("%4d %-5s %2d %2.2f", itemNumber, description, numInInventory, price);
}
public static void main(String[] args) {
try (Scanner file = new Scanner(Paths.get("clothes.txt"))) {
while (file.hasNextLine()) {
String record = file.nextLine();
String[] fields = record.split("\\s+");
if (fields.length == FIELDS) {
int itemNumber = Integer.parseInt(fields[0]);
String description = fields[1];
int numInInventory = Integer.parseInt(fields[2]);
double price = Double.parseDouble(fields[3]);
RetailItem item = new RetailItem(itemNumber, description, numInInventory, price);
System.out.println(item);
}
}
}
catch (IOException xIo) {
xIo.printStackTrace();
}
}
}
I think the way that I would do is, like you said, parse each line into separate strings and then assign each piece to instance variables of the object you are building.
I have done something like this before, maybe it can be helpful.
Scanner fileScan;
File babyNameFile = new File("yob2015.txt");
try {
fileScan = new Scanner(babyNameFile);
} catch (FileNotFoundException e) {
System.out.println("File does not exist");
return;
}
String currentLine;
int numberOfGirlsNames = 0;
while (fileScan.hasNextLine()) {
String[] values;
currentLine = fileScan.nextLine();
values = currentLine.split(",");
if (values[1].equals("F")) {
numberOfGirlsNames = numberOfGirlsNames+1;
}
}
System.out.println("Number of female names was "+numberOfGirlsNames);

How to test my java program?

I was asked to write this part of a program and then test it in the following way:
Add some statements to the main method that create two or three contact instances, add them to the address book, and then search for one or two of them. Display the result of each search to see if they were retrieved correctly. Then remove one of them and show the list to be sure that it was removed correctly.
I wasn't entirely sure how to test this. What should I write in the main class? Also, is the rest of the code correct?
Do this for Contact Class:
Create this class in the client package. This class should have three fields (An email address, A full name, A nick name). All of these should be Strings.
Provide two constructors: one full constructor (parameters for all three member variables), and one that has a parameter only for the email address. This second constructor will leave the other two fields null.
Add a toString method (and use the #Override annotation) that works like this:
Contact c1 = new Contact("jenny#gmail.com");
c2.toString() should return "jenny#gmail.com".
Contact c2 = new Contact("jenny#gmail.com", "Jennifer Abott", "jenny");
c2.toString() should return "Jennifer Abott (jenny) jenny#gmail.com".
Do this for AddressBook Class:
Create this class and have a single member variable of type ArrayList<Contact>. Define the variable, don't just declare it
You do not need a constructor.
Write an add method that has a Contact parameter and adds the contact to the contact list.
Write a remove method that has a String parameter, which is the nick name of the contact to remove. It returns nothing. Remove that contact from the contact list. Hint: Use the search method that you already wrote in order to find the contact, then remove that contact from the contact list. See the online documentation for ArrayList for how the remove method works in the ArrayList class. Be sure that the remove method does not crash if you give it a nick name that does not exist in the list.
Write a search method that has a String parameter, which is a nick name to search for. The method must iterate over the contact list. If the nick name is found (use .equals), return that contact. If no contact is found, return null.
Write a show method that displays each Contact instance. It has no parameters and returns nothing. Display one contact per line, and number each line. Like this:
Jeff Meunier (jeff)
Bill Gates (money)
Vladimir Putin (vman)
Make sure that the numbers shown start at 1, not at 0.
Contact class:
package client;
public class Contact
{
private String _emailAddress;
private String _fullName;
private String _nickName;
public Contact(String emailAddress, String fullName, String nickName)
{
_emailAddress = emailAddress;
_fullName = fullName;
_nickName = nickName;
}
public Contact(String emailAddress)
{
_emailAddress = emailAddress;
}
#Override
public String toString()
{
if(_fullName == null)
{
return "<" + _emailAddress + ">";
}
else
{
return _fullName + " " + "(" + _nickName + ")" + " " + "<" + _emailAddress + ">";
}
}
}
Address Book class:
package client;
import java.util.ArrayList;
public class AddressBook
{
public ArrayList<Contact> contactList = new ArrayList<Contact>();
public void add(Contact _contact)
{
contactList.add(_contact);
}
public Contact search(String nickName)
{
for (int n=0; n < contactList.size(); n++)
{
if(contactList.get(n).equals(nickName))
{
return contactList.get(n);
}
}
return null;
}
public void remove(String nickName)
{
if(search(nickName) != null)
{
contactList.remove(search(nickName));
}
}
public void show()
{
for(int n=0; n<contactList.size(); n++)
{
System.out.println(n++ + ". " + contactList.get(n).toString());
}
}
}
I don't have much in the main class yet, but here it is:
Main Class
import java.util.ArrayList;
import client.Contact;
public class Main
{
public static void main(String[] args)
{
Contact c1 = new Contact("jeffm#engr.uconn.edu");
Contact c2 = new Contact("jeffm#engr.uconn.edu", "Jeff Meunier", "jeff");
}
}
"Add some statements to the main method that create two or three contact instances, add them to the address book, and then search for one or two of them. Display the result of each search to see if they were retrieved correctly. Then remove one of them and show the list to be sure that it was removed correctly."
If this is your task then:
1. You created a few contact instances, so this is done, but create a few more with all the available class fields set (this will be needed for the next steps)
2. Now you must create an instance of your address book class.
AddressBook addressBook = new AddressBook();
Add the created contacts to the adress book
addressBook.add(c1);
addressBook.add(c2);
// other contacts
Use the show method to see if everything is correct.
addressBook.show();
Try removing one and show the available contacts again to see if this worked.
addressBook.remove(c1.getNickName()); // Make get method for the nickname
addressBook.show();
Then search for a contact with a certain name, assign this to a new contact object and then print something from it to acknowledge that the object is the correct one.
Here your logic can break, because your search does not cover the possibillity that you have more then one contacts with the same name. So you should return an List of found contacts instead of one contact. Implement this and search again (make sure you search for objects with unique and non-unique names so the testing is acceptable).
Your search testing will look something like this at the end:
List <Contact> contacts = addressBook.search("John");
for(Contact contact in contacts) {
System.out.println(contact.toString());
}
Now since your delete method depends on the search, you will have to change it a bit too. When you do that, test the remove method again as above.
Work out every step until it works fine and your done.
P.S. You may want to print some description between different testing prints, so you can see clearly the results in the output

Can I put a String in an Arraylist when a object is created?

I want to make a program where you can name a String("weapon" for example)and then add that String to a ArrayList. But without typing it yourself like:
MyArrayList.add(Egg); //for example
So that the new Object automatically add to the Arraylist.
So what I did, I created an Arraylist that will hold the weapon names. I made a method, where you can "make" in the main class a object with the weapon name.But how do i make something that when a object (in the main class)is created, it automatically add it self to the arraylist.
(Sorry for bad explaining, I'm from The Netherlands so... If it's a bad explaining please tell me so i can improve it)
Maybe I completely misunderstand it, but do you want to do something like this?
private ArrayList<YourObject> list;
public YourMainClass(){
list = new ArrayList<YourObject>();
}
public void onAdd(String weaponName){
list.add(new YourObject("weaponName")); // <- this being your issue
}
With YourObject being something like:
public class YourObject
{
private String name;
public YourObject(String n){
setName(n);
}
public void setName(String n){
// Perhaps an if-else to check if n isn't null, nor emtpy?
name = n;
}
public String getName(){
return name;
}
}
Based on my interpretation of your problem, you want to have the user create a weapon name and add it to the ArrayList without having to manually add the code to add it?
A basic way to get String input from a user:
Scanner inputscan = new Scanner(System.in); //reads input from command line
String weapon = inputscan.nextLine(); //waits for user input
MyList.add(weapon);
That way, every time you call the "make" method with that code in it, it will prompt the user to type a weapon name, then the weapon name gets stored in the array.
I think you want to initialize the List with an object in it:
Try using an instance block, like this:
List<String> list = new ArrayList<String>() {{
add("Egg");
}};
Add the command to add the object to the collection in the constructor.( But this ill advise)
You can create an auxiliary class that will create that object and label to the collection.
class WeaponFactory
{
Collection c;
public WeaponFactory(Collection coll){c=coll;}
public Weapon makeWeapon(String text) // Makes sense when the object is not String , like a Weapon class which also contains stats or something
{
Weapon w = new Weapon(text)
c.add(w);
return w;
}
}
class Weapon
{
String name;
public Weapon(String text)
{
name = text;
}
}

Java Inventory - ADT class & File Input troubles

I've hit a roadblock with this program.
I have a program that involves creating a program that involves the "inventory" of Cadillac, and among all else, I cannot find answers to my questions.
I just do not know what to do. I'll provide the directions and then post the syntax I have so far.
Here is what I have to do:
inventory for a fictional Cadillac Dealership and allows the inventory to be searched to display a list of cars that meet specific criteria.
create an ADT class called Cadillac which contains four fields of instance data: Strings for model name, stock number and color, and an integer for price. The class contains one Constructor, which receives values for all four instance fields, and assigns the parameter values to the instance variables. The class also contains a simple accessor method and mutator method for each field of instance data.
When the program is ran, it loads the inventory from a file, "inventory.dat".
Here is a sample of the contents of the file:
DTS 11210 Glacier White 42706
Escalade 66502 Crimson Pearl 65547
XLR 58362 Radiant Bronze 78840
SRX 16218 Radiant Bronze 44522
Each line (each record) contains 4 fields of data: strings for model name, a 5–digit stock number, and color, and an integer for price. The delimiter between the fields is a tab character (“\t”).
In main(), create an array of Cadillac objects, read in a record from the file, split it into its 4 fields, create a Cadillac object and add it to the array.
the inventory file changes and your program needs to work no matter how many records are in the file. You are guaranteed there will never be more than 100 records in the file (they only have room for 100 cars on the lot), and that each record will contain exactly 4 fields of valid data.
The user can search the inventory two ways: by model name and by price. After you load the inventory, ask the user which search they want to do. If they indicate “by model name”, have them enter the name to search for. The valid model names are: DTS, Escalade, ESV, EXT, SRX, STS, and XLR. Search the inventory for all cars with that name and display a table of results on the console screen.
-When the user indicates he/she wants to search by price, have them enter the price to search
for, then perform the search, displaying all cars that have a price within $3,000 of the search
price.
- The program should loop to do as many searches as the user wants. Let the user end the
program by clicking a “Cancel” button when asked for the type of search they want to perform.
A “Cancel” button on the second question (the model or price to search for) should not end the
program, but your code should recognize it as an invalid entry, and not throw an exception.
Besides the list output, all input and output in the program should be with JOptionPane dialogs.
Here is what I have so far:
import java.util.Scanner;
import java.io.*;
public class Inventory {
public static void main ( String[] args )
{
String line;
String[] fields;
String[] items;
int count = 0;
int recCount;
Cadillac[] list = new Cadillac[100];
try
{
BufferedReader br = new BufferedReader( new FileReader( "inventory.dat" ) );
line = br.readLine();
while( line != null )
{
fields = line.split( "\t" );
items[count++] = new Cadillac( fields[0], fields[1], fields[2],
fields[3] );
line = br.readLine();
}
br.close();
}
catch( IOException e )
{
System.out.println( "Can't open input file. Program terminating." );
System.exit( 1 );
}
}
public static int loadArray(Cadillac[] items)
{
}
}
class Cadillac {
//Instance data
private String model;
private String stockNum;
private String color;
private int price;
//Constructor
public Cadillac(String mdl, String stckNum, String clr, int prc)
{
model = mdl;
stockNum = stckNum;
color = clr;
price = prc;
}
//Set of Accessor and Mutator Methods
public String getModel(){
return model;
}
public void setModel(String newModel){
model = newModel;
}
public String getStockNum(){
return stockNum;
}
public void setStockNum(String newStockNum){
stockNum = newStockNum;
}
public String getColor(){
return color;
}
public void setColor(String newColor){
color = newColor;
}
public int getPrice(){
return price;
}
public void setPrice(int newPrice){
price = newPrice;
}
}
PLEASE HELP! I do not have any other idea of what to do.
In regards to your comment:
It is saying that it cannot find the symbol constructor Cadillac
Your only constructor defined for Cadillac has parameters (String, String, String, int) but when you try to instantiate the object in main, you pass it four Strings. Java is throwing an error because it can't find the correct constructor.
Either pass the last parameter as an int or create a new constructor for your arguments.
Your most immediate problem is that the signature of your data objects constructor is incompatible with the way you are calling it. You have declared your constructor as so:
public Cadillac(String mdl, String stckNum, String clr, int prc)
It takes three string arguments and an int, but you are calling it with four strings:
new Cadillac( fields[0], fields[1], fields[2], fields[3] );
Thats the source of the compile error you reported seeing. You should convert your last String to an int.
new Cadillac( fields[0], fields[1], fields[2], Integer.parseInt(fields[3]).intValue() );
Apart from that there is another glaring error in your code. You declare an array of strings, but are attempting to store instances of 'Cadillac' into it:
String[] items;
// ...
items[count++] = new Cadillac( ... );
I won't code your entire homework for you, but my advise would be to first right down in plain English sentences, each task that needs to be accomplished in order to complete the overall program. Then start translating each individual sentence into code, ideally in the form of methods on your classes that can be called. As you run into issues, come back and ask specific questions and I'm sure there will be someone here willing to help you more.
Good luck.

Categories