Create an array of objects - java

I'm fairly new to java, but I understand programming concepts. I'm working on a trading game. I want to be able to list every item I want in a .txt file and read down the list making an instance of Item() object for each. I know how to read the input, it's then sorting them into an array that is hard to figure out.
Is an array the right way to go for this? Or is there some other way to handle my item information?
public class Item {
File itemList = new File("Items.txt");
ArrayList<Item> Items = new ArrayList<>();
String line = "";
String name = "";
int price = 0;
int ID = 0;
public void setItem (String theName, int thePrice, int theID)
{
name = theName;
price = thePrice;
ID = theID;
}
public void Initialize () throws FileNotFoundException
{
Scanner scan = new Scanner(itemList);
do
{
do
{
line = scan.nextLine();
while (!line.startsWith("#")) {line = scan.nextLine();}
if (line.matches(".*\\d+.*"))
{
price = Integer.parseInt(line);
}else
{
name = line;
}
}while(!line.equals(""));
Items.add(new Item());
ID++;
}while (!line.equals("end"));
}
}

There are several ways you can store your items maybe the easiest way is doing it with an array list.
ArrayList<Items> items = new ArrayList<Items>();
And assuming that you create new items with your input data:
/*This goes in a loop where you read in currentInputData*/
items.add(new Item(currentInputData));
For further information about manipulating ArrayLists refer to javadoc: https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

Related

Getting size and comparing attribute value from ArrayList in other class

I am trying to create a method which creates a result for a athlete in a competition. I have an ArrayList with the athletes in another class and now I want this method to be able to find the size of the ArrayList and also compare one int attribute of every Athlete with the input number. This is what I have so far, Im really stuck. So my quetions to you are: How do I get my for loop to see the size of the ArrayList athletes? and what is a proper way to check whether or not the input has a matching athlete in the ArrayList(I want it to print out if there is no match)? Thank you
public class ResultList {
Scanner scanner = new Scanner(System.in);
ArrayList<Result> resultList = new ArrayList<Result>();
public ResultList() {
ArrayList<Athlete> temp = new AthleteList().getArrayList();
}
void addResult() {
int competetionNumber;
System.out.print("What is the athletes competetionnumber?");
competetionNumber = scanner.nextInt();
scanner.nextInt();
for (int i = 0; i < athletes.size(); i++) {
}
}
}
Other class with the Athlete ArrayList:
public class AthleteList {
ArrayList<Athlete> athletes = new ArrayList<Athlete>();
public AthleteList () {
}
public ArrayList<Athlete> getArrayList() {
return athletes;
}
You should create a variable that points to the AthleteList class. Then you can see that in the addResult method you just get the ArrayList from the AthleteList and call size() on it and iterate over the Athletes and check the completionNumber(You didn't post the Athlete class so I'm assuming there is a completionNumber property). I create a matched variable to hold on to the matched Athlete. After the loop I check to see if one matched and print out the result.
Hope this helps.
public class ResultList
{
Scanner scanner = new Scanner(System.in);
ArrayList<Result> resultList = new ArrayList<Result>();
AthleteList athleteList;
public ResultList()
{
athleteList = new AthleteList();
}
void addResult()
{
int competetionNumber;
System.out.print("What is the athletes competetionnumber?");
competetionNumber = scanner.nextInt();
scanner.nextInt();
Athlete matched = null;
List<Athlete> athletes = athleteList.getArrayList();
for(int i = 0; i < athletes.size(); i++)
{
if(athlete.completionNumber == completionNumber)
{
//you found a match!!
matched = athlete;
}
}
if(matched == null)
{
System.out.println("No Match Found for " + completionNumber);
}
else
{
System.out.println("Found match: " + matched.toString());
}
}
}
NOTE:
Not sure you need the AthleteList class. It's just holding an ArrayList. If that's all that class will ever do then I suggest you just using an ArrayList. It will make your code cleaner.

Trying to display contents of ArrayList. Getting [Ljava.lang.String;#232204a1

I am attempting to output the contents of an ArrayList, but no matter which approach I try I seem get the location of the Array rather than the contents of the Array. Running each of the following together gives me:
run:
[[Ljava.lang.String;#55f96302, [Ljava.lang.String;#232204a1, [Ljava.lang.String;#4554617c, [Ljava.lang.String;#7f31245a, [Ljava.lang.String;#2503dbd3, [Ljava.lang.String;#5cad8086]
[Ljava.lang.String;#232204a1
[Ljava.lang.String;#232204a1
[Ljava.lang.String;#232204a1
Here's the code snippet:
// Each of the following approaches results in
// [Ljava.lang.String;#232204a1
// instead of the actual value of the ArrayList.
String test = accountNumbers.get(1);
System.out.println(test);
System.out.println(accountNumbers.get(1));
System.out.println(accountNumbers.get(1).toString());
// This actually outputs:
// [[Ljava.lang.String;#55f96302, [Ljava.lang.String;#232204a1, [Ljava.lang.String;#4554617c, [Ljava.lang.String;#7f31245a, [Ljava.lang.String;#2503dbd3, [Ljava.lang.String;#5cad8086]
String str = Arrays.toString(accountNumbers.toArray());
System.out.println(str);
I'm not really sure what's causing this. Is there some way to get the contents to display?
EDIT: Here's the entire method. An answer on another question (here) advised me to try using ArrayList instead of the approach I was using. I adapted the suggestion, but I felt that the problems were better placed in a new question rather than as an edit to that question.
protected static void loadAccountInformationFromFile() throws Exception
{
Scanner account = new Scanner(new File(INPUT_ACCOUNT_FILE)).useDelimiter(",");
int sortCount = 1;
List<String> accountNumbers = new ArrayList<>();
List<String> firstNames = new ArrayList<>();
List<String> lastNames = new ArrayList<>();
List<String> balances = new ArrayList<>();
List<String> lastVariables = new ArrayList<>();
do {
String[] temp1 = account.next().split(",");
String temp2 = "" + temp1;
if (sortCount == ACCOUNT_NUMBER_COUNT) {
accountNumbers.add(temp2);
} else if (sortCount == FIRST_NAME_COUNT) {
firstNames.add(temp2);
} else if (sortCount == LAST_NAME_COUNT) {
lastNames.add(temp2);
} else if (sortCount == BALANCE_COUNT) {
balances.add(temp2);
} else if (sortCount == LAST_VARIABLE_COUNT) {
lastVariables.add(temp2);
}
if (sortCount < MAX_VALUES_PER_LINE) {
sortCount++;
} else {
sortCount = 1;
}
} while (account.hasNext());
// Each of the following approaches results in
// [Ljava.lang.String;#232204a1
// instead of the actual value of the ArrayList.
String test = accountNumbers.get(1);
System.out.println(test);
System.out.println(accountNumbers.get(1));
System.out.println(accountNumbers.get(1).toString());
// This actually outputs:
// [[Ljava.lang.String;#55f96302, [Ljava.lang.String;#232204a1, [Ljava.lang.String;#4554617c, [Ljava.lang.String;#7f31245a, [Ljava.lang.String;#2503dbd3, [Ljava.lang.String;#5cad8086]
String str = Arrays.toString(accountNumbers.toArray());
System.out.println(str);
account.close();
// I want to adapt what I previously used to access the ArrayLists.
// Bank bank = new Bank();
//
// bank.openAccount(new CheckingAccount(10100, new Customer("Adam", "Apple"),500.00,false));
// bank.openAccount(new CheckingAccount(10101, new Customer("Beatrice", "Bagel"),2000.00,true));
// bank.openAccount(new SavingsAccount(2010, new Customer("Adam", "Apple"),5000.00,0.02));
}
EDIT 2: Here are the class variables:
private final static String INPUT_ACCOUNT_FILE = "accountInfo.txt";
private static final int ACCOUNT_NUMBER_COUNT = 0;
private static final int FIRST_NAME_COUNT = 1;
private static final int LAST_NAME_COUNT = 2;
private static final int BALANCE_COUNT = 3;
private static final int LAST_VARIABLE_COUNT = 4;
private final static int MAX_VALUES_PER_LINE = 5;
EDIT 3: For the benefit of those who may read this question late and be confused by some of the comments on the correct answer, part of my issue was related to an issue with the text file itself. This is an example of the formatting of the text file:
10100,First,Last,Balance,value
10101,First,Last,Balance,value
20100,First,Last,Balance,value
Also: To get the ArrayLists to store the correct strings I had to change sortCount from:
int sortCount = 1;
to
int sortCount = 0;
Because when it was set at 1 it would store the first name in the account number string.
The problem is not in your "displaying" but in the way you read the contents from the file.
Your code prints out correctly "addresses" because the strings in accountNumbers instance are really these values (because you put array of strings into one single string). So what really happens is that in your temp2 String is your temp1.toString().
You are using wrong delimiter (you should use default one for whitespaces instead):
Scanner account = new Scanner(new File(INPUT_ACCOUNT_FILE));
And then assign values like:
if (temp1.length > ACCOUNT_NUMBER_COUNT) {
accountNumbers.add(temp1[ACCOUNT_NUMBER_COUNT]);
if (temp1.length > FIRST_NAME_COUNT) {
firstNames.add(temp1[FIRST_NAME_COUNT]);
if (temp1.length > LAST_NAME_COUNT) {
lastNames.add(temp1[LAST_NAME_COUNT]);
if (temp1.length > BALANCE_COUNT) {
balances.add(temp1[BALANCE_COUNT]);
if (temp1.length > LAST_VARIABLE_COUNT) {
lastVariables.add(temp1[LAST_VARIABLE_COUNT]);
}
Your temp2 and sort variables are not needed.
Anyway it is a bit weird to use these collections. I would rather suggest to do it like:
Scanner scanner = new Scanner(new File(INPUT_ACCOUNT_FILE));
Collection<Account> bank = new ArrayList<>();
while (scanner.hasNext()) {
String[] fields = scanner.next().split(",");
if (fields.length < MAX_VALUES_PER_LINE) {
continue; // incomplete row, skip it or maybe throw some exception?
}
String number = fields[ACCOUNT_NUMBER_COUNT];
Customer customer = new Customer(fields[FIRST_NAME_COUNT], fields[LAST_NAME_COUNT]);
double balance = Double.valueOf(fields[BALANCE_COUNT]);
String type = fields[LAST_VARIABLE_COUNT];
Account a = null;
switch (type) {
case "N": {
a = new CheckingAccount(number, customer, balance);
break;
}
case "0.02": {
a = new SavingsAccount(number, customer, balance);
break;
}
default: {
continue; // unknown type of account, skip it or maybe throw some exception?
}
}
bank.add(a);
}
String temp2 = "" + temp1;
You are trying to concat a blank with a string array, this is equals with
String temp2 = "" + temp1.toString();
Note that toString() of Array will return object references, not the value.
So you should try to convert array to some Java Collection class that implements the toString() method like ArrayList
String temp2 = "" + Arrays.asList(temp1).toString();
or you can also do
String temp2 = "" + Arrays.toString(temp1);
Both will give you the String value (and some "[" and "]" too, I guess, because of the toString() implementation of ArrayList and Arrays, you can work it out).

Creating array from reading a file

I have a file with the following:
5
212:Float On:Modest Mouse
259:Cherub Rock:Smashing Pumpkins
512:Won't Get Fooled Again:The Who
417:Teen Age Riot:Sonic Youth
299:PDA:Interpol
I need to create a array but I need to take into account the integer it starts with, then read the rest as strings taking into account the initial line containing only an integer. I've made the method to read the file and print, just don't know how to split it up.
An example of how to do it:
String s = "212:Float On:Modest Mouse"; // your input - a line from the file
String[] arr = s.split(":");
System.out.println(arr[0]); // your int
// The rest of the array elements will be the remaining text.
// You can concatenate them back into one string if necessary.
you can read file using Scanner
readlines = new Scanner(filename);
while(readlines.hasNextLine())
{
String line = readlines.nextLine();
String[] values = line.split(":");
int firstColumn = -1;
if (values.length > 0) {
try {
firstColumn = Integer.parseInt(values[0]);
} catch (NumberFormatException ex) {
// the value in the first column is not an integer
}
}
}
I've grown a habit of reading the entire file into a List, then handling the List in memory. Doing this is not the only option.
Once I have the file read in, I look at the first line to know how many tracks to expect in the remaining file. I then would loop through the remaining List to either get the number of tracks from the first line or until I reach the end of the list, in the event that the number of tracks (from the first line) exceeds the actual amount of tracks that are in the file.
As I go through the tracks I would use substring to break the line apart, and convert just the first part.
Update
Base on your comment, I've updated to use split instead of substring. Then some basic alignment formatting for output
public static void main(String[] args) throws Exception {
String yourFile = "path to your file.txt";
List<String> yourFileLines = new ArrayList<>(Files.readAllLines(Paths.get(yourFile)));
// You know the first line is suppose to be the number of tracks so convert it to a number
int numberOfTracks = Integer.valueOf(yourFileLines.get(0));
// Either go to the number of tracks or till the end of file
List<Track> tracks = new ArrayList<>();
for (int i = 1; (i <= numberOfTracks && i < yourFileLines.size()); i++) {
String currentFileLine = yourFileLines.get(i);
String[] currentFileLinePieces = currentFileLine.split(":");
Track currentTrack = new Track();
currentTrack.TrackTime = Integer.valueOf(currentFileLinePieces[0]);
currentTrack.TrackTitle = currentFileLinePieces[1];
currentTrack.TrackArtist = currentFileLinePieces[2];
tracks.add(currentTrack);
}
System.out.println(String.format("%-20s\t\t%-20s\t\t%-20s", "TITLE", "ARTIST", "TIME"));
System.out.println(String.format("%-20s\t\t%-20s\t\t%-20s", "-----", "------", "----"));
for (Track currentTrack : tracks) {
System.out.println(currentTrack);
}
}
public static class Track {
public int TrackTime;
public String TrackTitle;
public String TrackArtist;
#Override
public String toString() {
return String.format("%-20s\t\t%-20s\t\t%-20d", TrackTitle, TrackArtist, TrackTime);
}
}
Results:
Here's an example using a Scanner, and breaking everything into methods. You should be able to use List and ArrayList. Results are the same.
public static void main(String[] args) throws Exception {
String yourFile = "data.txt";
List<String> yourFileLines = readFile(yourFile);
if (yourFileLines.size() > 0) {
// You know the first line is suppose to be the number of tracks so convert it to a number
int numberOfTracks = Integer.valueOf(yourFileLines.get(0));
List<Track> tracks = getTracks(numberOfTracks, yourFileLines);
printTracks(tracks);
}
}
public static List<String> readFile(String pathToYourFile) {
List<String> yourFileLines = new ArrayList();
try {
File yourFile = new File(pathToYourFile);
Scanner inputFile = new Scanner(yourFile);
while(inputFile.hasNext()) {
yourFileLines.add(inputFile.nextLine().trim());
}
} catch (Exception e) {
System.out.println(e);
}
return yourFileLines;
}
public static List<Track> getTracks(int numberOfTracks, List<String> yourFileLines) {
List<Track> tracks = new ArrayList();
// Either go to the number of tracks or till the end of file
for (int i = 1; (i <= numberOfTracks && i < yourFileLines.size()); i++) {
String currentFileLine = yourFileLines.get(i);
String[] currentFileLinePieces = currentFileLine.split(":");
Track currentTrack = new Track();
currentTrack.TrackTime = Integer.valueOf(currentFileLinePieces[0]);
currentTrack.TrackTitle = currentFileLinePieces[1];
currentTrack.TrackArtist = currentFileLinePieces[2];
tracks.add(currentTrack);
}
return tracks;
}
public static void printTracks(List<Track> tracks) {
System.out.println(String.format("%-20s\t\t%-20s\t\t%-20s", "TITLE", "ARTIST", "TIME"));
System.out.println(String.format("%-20s\t\t%-20s\t\t%-20s", "-----", "------", "----"));
for (Track currentTrack : tracks) {
System.out.println(currentTrack);
}
}
public static class Track {
public int TrackTime;
public String TrackTitle;
public String TrackArtist;
#Override
public String toString() {
return String.format("%-20s\t\t%-20s\t\t%-20d", TrackTitle, TrackArtist, TrackTime);
}
}

Sorting an array list with a delimiter

I have been stuck on this problem for so long and i have no idea what to do.
Basically i have a text file with people names then student number then prize money like this:
Green%3243%1000
Kevin%7657%400
Frank%345%10000
Bob%5435%5000
Stefan%31231%1000
Javis%4532%100
IronMan%5435%2000
Lamp%534%3000
What i want to be able to do is sort the array based on the last number.
I tried this abomination (Don't bother reading it its garbage):
boolean flag = true;
String temp;
int temp1;
int temp2;
while (flag){
flag = false;
for(int j=0; j < list.size() -1; j++ ){
System.out.println(list.get(j));
Scanner s = new Scanner(list.get(j)).useDelimiter("%");
s.next();
s.next();
temp1 = s.nextInt();
Scanner s2 = new Scanner(list.get(j+1)).useDelimiter("%");
s2.next();
s2.next();
temp2 = s2.nextInt();
if (temp1 < temp2){
temp = list.get(j);
list.add(j, list.get(j+1));
list.add(j+1,temp);
flag = true;
}
}
}
But its just infinitely looping. My though while making it was just patching array lists into a bubble sort.
If anyone has any ideas and is willing to share them it will be greatly appreciated.
Java is an object-oriented language, so I'll just use objects:
Create a Student object with the three values you want to store (and a toString() method to print them separated by "%":
public class Student {
private final String name;
private final int number;
private final int prizeMoney;
public Student(final String name, final int number, final int prizeMoney) {
this.name = name;
this.number = number;
this.prizeMoney = prizeMoney;
}
#Override
public String toString() {
return name+"%"+number+"%"+prizeMoney;
}
public int getPrizeMoney() {
return prizeMoney;
}
}
Read your lines as Student objects, and store them in a List:
final Scanner scan = new Scanner(new File("/path/to/StudentsList"));
final List<Student> students = new ArrayList<Student>();
while (scan.hasNextLine()) {
final Scanner line = new Scanner(scan.nextLine());
line.useDelimiter("%");
students.add(new Student(line.next(), line.nextInt(), line.nextInt()));
line.close();
}
scan.close();
Order the List with a custom Comparator, and print it:
students.sort(new Comparator<Student>() {
#Override
public int compare(final Student s1, final Student s2) {
return s1.getPrizeMoney()-s2.getPrizeMoney();
}
});
for (final Student student: students)
System.out.println(student);
Output:
Javis%4532%100
Kevin%7657%400
Green%3243%1000
Stefan%31231%1000
IronMan%5435%2000
Lamp%534%3000
Bob%5435%5000
Frank%345%10000
Here's something for you to get head started.
Create a map for prize money => line as key/value pair
Read each line in the file, parse it and put key/value pair in the above map
Once your map is ready, convert the keys entry set into the collections like list
Sort the collections, using Collections.sort()
Iterate over the created map, and for each value in the collection get the corresponding value from the map.
Hope this helps you to get the workflow.
Id consider creating a 3d array here 8x8x8 from right to left in the array is row, col, and in so [0][0][1] is block one or kevin [0][1][1] is 7657 [1][1][1] is 400. I like this way because not only does it give each 'item' an array it allows you to keep it organized and easily accessable

Java: Combine 2 List <String[]>

I have two List of array string. I want to be able to create a New List (newList) by combining the 2 lists. But it must meet these 3 conditions:
1) Copy the contents of store_inventory into newList.
2) Then if the item names in store_inventory & new_acquisitions match, just add the two quantities together and change it in newList.
3) If new_acquisitions has a new item that does not exist in store_inventory, then add it to the newList.
The titles for the CSV list are: Item Name, Quantity, Cost, Price.
The List contains an string[] of item name, quantity, cost and price for each row.
CSVReader from = new CSVReader(new FileReader("/test/new_acquisitions.csv"));
List <String[]> acquisitions = from.readAll();
CSVReader to = new CSVReader(new FileReader("/test/store_inventory.csv"));
List <String[]> inventory = to.readAll();
List <String[]> newList;
Any code to get me started would be great! =]
this is what i have so far...
for (int i = 0; i < acquisitions.size(); i++) {
temp1 = acquisitions.get(i);
for (int j = 1; j < inventory.size(); j++) {
temp2 = inventory.get(j);
if (temp1[0].equals(temp2[0])) {
//if match found... do something?
//break out of loop
}
}
//if new item found... do something?
}
I would start by building the newList as a HashMap or TreeMap instead of a List. This makes it easy to search for the matching record. Furthermore, I would convert the String[] to a custom object (e.g. Record) that contains the name, quantity, cost and price field. This would take care of copying the information. The you could try something like this:
Map<String, Record> newMap = new TreeMap<String, Record>();
for(String[] ss : acquisitions) {
Record rec = Record.parse(ss); // For requirement (1)
newMap.put(rec.getName(), rec);
}
for(String[] ss : inventory) {
Record rec = Record.parse(ss); // For requirement (1)
if(newMap.containsKey(rec.getName())) {
// For requirement (2)
// The mergeWith method can then add quantities together
newMap.get(rec.getName()).mergeWith(rec);
} else {
// For requirement (3)
newMap.put(rec.getName(), rec);
}
}
edit
An extra advantage of having a Record object, is that it can be printed to screen much easier by implementing the toString function.
public class Record implements Comparable<Record> {
public static Record parse(String[] ss) {
// TODO: implement some basic parsing
}
private String name;
private int quantity;
private BigDecimal cost, price;
private Record() {}
public String getName() { return name; }
public int getQuantity() { return quantity; }
public BigDecimal getCost() { return cost; }
public BigDecimal getPrice() { return price; }
public int compareTo(Record other) {
return this.name.compareTo(other.name);
}
public String toString() {
return name;
}
}

Categories