Store and query objects in collection java - java

I'm working on a java project right now and am stuck. I'm trying to figure out how to first store a person object that has several elements like first name, last name, and ID. I know it's possible to create different collections for each part of the object but I'm wondering is it possible to create and query all elements in one collection? That is to say, after storing the objects in the collection, I want to interate through the collection to search for first name, last name, and ID.
This is my current code:
public static void processRecords(String filenameIn)throws Exception{
Scanner input = new Scanner(new File("students_mac.txt")); //retrieves data from file and stores
input.nextLine();
while (input.hasNextLine()) { //enters loop to process individual records and print them
String line = input.nextLine();
String[] tokens=line.split("\t"); // splits lines by tabs
if(tokens.length!=4)
continue;
Person student = new Person(FirstName, LastName, ID, Year);
List<Person> list = new LinkedList<Person>();
list.add(student);
}
List<Person> list=new LinkedList<Person>();
for(Person student : list){
System.out.println(student);
}

All you need is to move List<Person> list = new LinkedList<Person>(); out of while loop.
Scanner input = new Scanner(new File("students_mac.txt")); //retrieves data from file and stores
input.nextLine();
List<Person> list = new LinkedList<Person>();
while (input.hasNextLine()) { //enters loop to process individual records and print them
String line = input.nextLine();
String[] tokens=line.split("\t"); // splits lines by tabs
if(tokens.length!=4)
continue;
list.add(new Person(FirstName, LastName, ID, Year));
}
for(Person student : list){
System.out.println(student);
}

Related

Searching a multi-dimensional array in a menu page

I'm trying to create a menu page that allows addition to the array, output of the array and to search by name. I'm struggling with the search part, as it is a multi-dimensional array. How do I search just the names part of each object?
I'm also not sure how to loop this so that they return to the main page after each request, and therefore the array remains updated with any new editions.
package qa.com.task;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import qa.com.task.Person;
public class Runner {
public static void main(String[] args) {
Person pp1 = new Person("Karen", 27, "DevOps Engineer");
Person pp2 = new Person("Jim", 24, "Software Engineer");
// Create array
ArrayList<Person> people = new ArrayList<Person>();
people.add(pp1);
people.add(pp2);
// Search array
Scanner scan = new Scanner(System.in);
System.out.println("---------------------MENU---------------------");
System.out.println("------Create--------Search-------Output All---");
System.out.println("------type c--------type s---------type o-----");
String request = scan.nextLine();
if (request.contains("c")){
//CREATE NEW PERSON
System.out.println("----------Create Request: Enter Name----------");
String newname = scan.nextLine();
System.out.println("-------------------Enter Age-------------------");
Integer newage = scan.nextInt();
scan.nextLine();
System.out.println("-------------------Job Title-------------------");
String newjobtitle = scan.nextLine();
Person ppnew = new Person(newname, newage, newjobtitle);
people.add(ppnew);
System.out.println("-----Updated Array with New Creation Request----");
System.out.println(Arrays.toString(people.toArray()));
}
if (request.contains("s")){
//SEARCH
System.out.println("----------Search Request: Enter Name----------");
String searchname = scan.nextLine();
}
if (request.contains("o")){
//OUTPUT DATABASE
System.out.println("----------------Output Request:----------------");
System.out.println(Arrays.toString(people.toArray()));
}
}}
You can filter your people list based on a person name.
List<Person> filteredPeople = people.stream()
.filter(person -> person.getName().contains(searchname)) // Filter condition
.collect(Collectors.toList()); // Get the result as list
Then you can do what you want with filteredPeople.
Otherwise you can use a traditional for loop to iterate over the list and "print" Persons who match the condition, something like below.
List<Person> people...;
boolean stop = false;
while(!stop) {
// print menu (with exit command)
// handle commands and if exit command, set stop = true.
}

How to use multiple delimiters to put objects into array

I am trying to figure out how to use a delimiter to begin the construction of a new object from a text file source.
An example of the txt data that I am using:
"1|Fred|Fish|fredfish#gamer.net|Ithroeann:2|Laurie|Nash|laurieeenash#gmail.com|Mazzzap:"
This is what I have so far to create the first object in the array, but I am wondering how to use the ":" as the second delimiter to build the second object.
I am thinking about using a loop to automate this process.
public class PlayerReader {
public static void main(String[] args) {
Scanner input = new Scanner(new File("commandline.txt"));
input.useDelimiter("|");
Player[] players = new Player[0];
while (input.hasNext()) {
String id = input.next();
String firstName = input.next();
String lastName = input.next();
String emailAddress = input.next();
String gamerTag = input.next();
Player newPlayer = new Player(id, firstName, lastName, emailAddress, gamerTag);
players = addPlayer(players, newPlayer);
}
}
}
I think you are asking about how to deal with the fact that your file has two delimiters -> | separating fields and : separating objects that contain fields.
It should be straightforward. Try following:
Read the entire file content in string.
String content = new String(Files.readAllBytes(Paths.get("commandline.txt")));
Separate the objects delimited by :
String[] objects = content.split(":");
Create a new empty list of your objects - players:
List<Player> players = new ArrayList<Player>();
Convert each object into player by using your business mapping and add each player thus obtained to the above list.
for (String object : objects) {
String[] fields = object.split("|");
player.add(new Player(fields[0], fields[1], ...);
}

How to create new object in a for loop?

I want to create some objects in a program using for loop. The parameters of the objects are accepted from key board. My question is how to create different objects in a for loop. Here is what I have.
import java.io.*;
import java.util.*;
public class TimeToGraduate {
public static void main(String[] args){
class Course{
Course (String name, String sem, int numOfPre){
this.name = name;
this.sem = sem;
this.numOfPre = numOfPre;
}
String name;
String sem;
int numOfPre;
}
Scanner scanner = new Scanner(System.in);
System.out.print("Input two integers here: ");
String totalCourse = scanner.nextLine();
String[] numOfCourse = totalCourse.split(" ");//[0] num of total course [1] max num per semester
for(int i = 0;i < Integer.parseInt(numOfCourse[0]); i++){
System.out.print("Please input course info here: ");
String courseInfo = scanner.nextLine();
String[] infoOfCourse = courseInfo.split(" ");
String courseName = infoOfCourse[0];
String courseSem = infoOfCourse[1];
int courseNumOfPre = Integer.parseInt(infoOfCourse[2]);
Course course = new Course(courseName,courseSem,courseNumOfPre);
//How to create different objects?
}
scanner.close();
}
}
You could save the objects you are creating in an array.
Before the for loop:
// create an empty array with the size of the total courses
int numOfCourses = Integer.parseInt(numOfCourse[0]);
Course courses[] = new Course[numOfCourses];
Inside the loop:
courses[i] = new Course(courseName, courseSem, courseNumOfPre);
Collection
The answer by Securo is correct. But rather than an array, it is more flexible and powerful to use a Collection. If you want to keep the objects in the order of their creation, use the List interface, with an ArrayList as the implementation.
Before the loop starts, define an empty List.
List<Course> courses = new ArrayList<>();
If you know the number of courses, pass that number as the initial size of the ArrayList. Helps performance and memory usage a little bit if the ArrayList need not be resized.
List<Course> courses = new ArrayList<>( numberOfCourses );
In your loop, instantiate the objects and add to the List.
Course course = new Course( … );
courses.add( course );

Java split and add elements into corrsponding data type arraylists

My problem is when a user enters text it should have two elements to split when using .split() however with the items it splits how do I put them into different lists so that I can use integer based list to make calculations.
e.g.
a user enters "skyrim , 100" the 'skyrim' entry is a string however with the number (integer) '100' I want to split it removing the comma and add it to a ArrayList for calculations and with other inputs added.
game name(String) , hours(integers) <- template
skyrim , 100
oblivion , 25
GTA V , 50
so the listed items above are user input with 2 arguments separated by a comma, which will be split, then I need to add them to different arraylists.
Scanner input = new Scanner(System.in);
Arraylist<String> game = new Arraylist<>();
Arraylist<Integer> hours = new Arraylist<>();
Arraylist<Object> allGameData = new Arraylist<>();
String gameEntry = input.nextLine().split(" , ");
allGameData.add(gameEntry);
foreach(object items : allGameData) {
System.out.println(items);
}
so from here I should have:
skyrim , 100 , oblivion, 25, GTAV , 50
How do i put the game names into the game list and the numbers into the hours list?
Well for starters, the class you should be using is ArrayList with a capital L. So you need to change:
Arraylist<String> game = new Arraylist<>();
Arraylist<Integer> hours = new Arraylist<>();
Arraylist<Object> allGameData = new Arraylist<>();
to this:
ArrayList<String> game = new ArrayList<>();
ArrayList<Integer> hours = new ArrayList<>();
ArrayList<Object> allGameData = new ArrayList<>();
After we have them initialized correctly we add to the ArrayList with #.add so in your case you would add to the game and hours list like:
game.add("some game");
hours.add(10);
When you split your input with input.nextLine().split(" , "); we are expecting a String array to be returned. Currently you are trying to set this to just a String instead of a String array.
while (true){
System.out.println("Enter \"game , hours\" or \"Quit\"");
String line = input.nextLine();
if (line.equals("Quit")) break;
allGameData.add(line);
String[] parsedData = line.split(" , ");
game.add(parsedData[0]);
hours.add(Integer.parseInt(parsedData[1]));
}
You can use Integer.parseInt(). The code you submitted looks pseudo-codey, but this is something like what You're going for:
String gameEntry = input.nextLine();
allGameData.add(gameEntry);
String[] splitGameEntry = input.nextLine().split(" , ");
game.add(splitGameEntry[0]);
hours.add(Integer.parseInt(splitGameEntry[1]));
I don't know exactly what you're trying to accomplish with this code, but you may want to organize the game/hours into a class that holds both values. Your code would then look something like this:
public class GameInfo
{
private String name;
private int hours;
public GameInfo(String name, int hours)
{
this.name = name;
this.hours = hours;
}
[getters/setters]
#Override
public String toString()
{
return name + ": " + hours + " hours played!";
}
}
public class Main
{
public void doSomething()
{
Scanner input = new Scanner(System.in);
List<GameInfo> gameInfo = new ArrayList<>();
String[] gameEntry = input.nextLint().split(" , ");
gameInfo.add(new GameInfo(gameEntry[0], Integer.parseInt(gameEntry[1]));
for(GameInfo gameInfoPiece : gameInfo)
{
System.out.println(gameInfoPiece);
}
}
}
Using this approach, you would be able to add as much information into the GameInfo class as you want. For instance, if you wanted to change hours to expectedHoursToComplete and add actualHoursToComplete, you could easily do that.
You may find it easier if you rethink your approach. Rather than have 3 separate lists why not store it all in a single Map<String,Integer> where the key is the game name and the value is the number of hours.
Your code would look something like the following:
Scanner scan = new Scanner(System.in);
Map<String, Integer> gameHoursMap = new HashMap<>();
String currentValue = scan.nextLine();
// Loop until you meet some criteria to end such as typing q or quit
while(!currentValue.equalsIgnoreCase("q")){
// You would need to handle when the value of currentValue doesn't fit what you would normally be expecting before doing the rest
String[] vals = currentValue.split(",");
// Call trim method on the String incase there is any lingering whitespace
gameHoursMap.put(vals[0].trim(), Integer.valueOf(vals[1].trim()));
currentValue = scan.nextLine();
}
You would obviously need to write some error handling for when the input doesn't fit with what you're expecting but you get the gist.
UPDATE:
If you wanted to have more complicated info stored for each game you could wrap it up in a custom class GameInfo and then have a Map<String,GameInfo> where the key is the name and the value is the GameInfo. This would allow you to retrieve all of the game info for a game just based on the name.
public class GameInfo {
private String name;
private int hoursPlayed;
private int level;
// etc
}
You would then amend the while loop to create the GameInfo object instead of just putting a String and int into the Map
// Create the GameInfo object from the corresponding input supplied by the user
GameInfo game = new GameInfo(vals[0].trim(), Integer.valueOf(vals[1].trim()), Integer.valueOf(vals[2].trim()));
// Put it in the map with the name as the key
gameMap.put(game.getName(), game);

Can you help, is there something wrong in my code

I have a main class and then when I divide each element (id, name, surname, ...) then I should to save it in the list in another class called Student, and there class students. There are errors such as "method Collection.add(String[]) is not applicable". So what is the problem?
public class ProjectWork{
public static void main(String[] args) throws IOException{
Scanner fin = new Scanner(new File("data.txt"));
int i;
String str,name="",surname="",id="";
String [] midterms = new String[3];
while(fin.hasNextLine()){
str = fin.nextLine();
StringTokenizer toks = new StringTokenizer(str,"|");
while(toks.hasMoreTokens()){
id = toks.nextToken();
name = toks.nextToken();
surname = toks.nextToken();
for(i=0;i<3;i++){
midterms[i] = toks.nextToken();
}
}
Student(id,name,surname,midterms);
}
}
public static void Student(String id, String name, String surname, String[] midterms) throws IndexOutOfBoundsException{
private List<String[]> students = new ArrayList<String[]>();
students.add(id);
students.add(name);
students.add(surname);
}
}
Because, see this line:
private List<String[]> students = new ArrayList<String[]>();
It accepts Array of string, where as you are adding only String like this:
students.add(id);
So you are getting that error. Either declare students like this:
private List<String> students = new ArrayList<String>();
Or add "String" array using add method.
You've declared that you collection, students should take String arrays...
List<String[]> students = new ArrayList<String[]>();
But you are trying adding String elements to it, which are not the same thing.
Either change it so it does add String[] arrays...
List<String[]> students = new ArrayList<String[]>();
students.add(new String[]{id,name, surname});
or redecalre it to take String
List<String> students = new ArrayList<String>();
students.add(id);
students.add(name);
students.add(surname);
Based on what I understand your code is trying to do, I think you want the first one.
(ps- Local variables cannot be declared with access modifiers (ie private), you'll want to get rid of that)
Overall, you code doesn't make a lot of sense. You're calling a static method Student, which creates a List, adds some elements to it and the discards all that work when it exist. Is Student suppose to be a class?
You are trying to add String objects to a List, change this because you are not adding three arrays of type String:
private List<String> students = new ArrayList<String>();
You declare the students type as Array of String. So you should add an array to the collection.
To add id, name, surname, You can declare the collection type as String.
ie List<String> students = new ArrayList<String>();
The method should be like this:
public static void Student(String id, String name, String surname, String[] midterms) throws IndexOutOfBoundsException {
//List<String[]> students = new ArrayList<String[]>();
List<String> students = new ArrayList<String>();
students.add(id);
students.add(name);
students.add(surname);
}

Categories