I recently posted a question about getting a NullPointerException whenever I called an array of objects. I have traced the problem back to some disconnect between the main method providing the data and the method in question (Team.sortPlayers()) receiving the data.
public class Project3 {
public static void main(String[] args) {
Input3 input = new Input3();
Team teams[] = new Team[input.NUMBER_OF_TEAMS];
Player players[] = new Player[input.NUMBER_OF_PLAYERS];
String playas[] = new String[input.NUMBER_OF_PLAYERS];
String temp;
String name;
for ( int i=0 ; i<input.NUMBER_OF_TEAMS ; i++ ) {
name = input.getNextString();
System.out.println(name);
for ( int j=0 ; j<input.NUMBER_OF_PLAYERS ; j++ )
{playas[j] = input.getNextString();
System.out.println(playas[j]);}
teams[i] = new Team(name, playas); //THIS LINE SENDS OVER THE DATA TO THE QUESTIONABLE METHOD
teams[i].sortPlayers();
System.out.println(teams[i]);
}
}
}
//------------------------------
//
//------------------------------
class Player {
public String[] name;
public Player(String inputname) {
name = inputname.split(" ");
}
public String[] getName() {
return name;
}
public String getFirstName() {
return name[0];
}
public String getLastName() {
String last = name[1];
return last;
}
}
//-----------------------
//
//-----------------------
class Team {
private String teamname;
public Player players[];
public Player temp;
public Team(String inputname, String plays[]) { //THIS METHOD RECEIVES A NULL FOR 'INPUTNAME' AND WHAT APPEARS TO BE A JIBBERISH (ex: Player#5bdf59bd, maybe a memory address?) FOR 'PLAYS[]'
inputname = teamname;
System.out.println(teamname);
players = new Player [plays.length];
for( int k=0 ; k<plays.length ; k++ )
{ System.out.println(inputname);
this.players[k] = new Player(plays[k]);
System.out.println(players[k]);
}
}
public void sortPlayers() {
int n = players.length;
for (int pass=1; pass < n; pass++){
for (int i=0; i < n-pass; i++) {
String playerName = players[i].getLastName();
String nextPlayerName = players[i+1].getLastName();
if(playerName.compareTo(nextPlayerName) > 0)
temp = players[i];
players[i] = players[i+1];
players[i+1] = temp;
}
}
}
}
If anyone could help me figure what is going on here, I'd be very grateful! I've marked the two problematic statements with comments, and a PasteBin of it all can be found below:
http://pastebin.com/QGALKbP6
"temp" should not be a member variable, it should be local to the if block in the sort method. and, because if its expanded scope, you are inadvertently clearing some members of your players array due to the fact that your "if" block is missing some braces.
if(playerName.compareTo(nextPlayerName) > 0) {
Player temp = players[i];
players[i] = players[i+1];
players[i+1] = temp;
}
generally, even though braces are optional in some circumstances, you should use them all the time to avoid subtle bugs like this.
Related
I am trying to call the array variables in the reference class, try to sort them using a user-defined method and call the method onto the case statement that will be invoked if the user chooses a particular number. I wanted to provide the user the option what attribute of a student will be sorted (i.e. name, course...) and show the sorted one dimensional array called in the case statements and invoked through the main method.
Here's the variables in the Reference class:
class RecordReference {
private int idNumber;
private String firstName = "";
private String middleName = "";
private String lastName = "";
private int age;
private String yearLevel;
private String course = "";
private double gwa;
public RecordReference(int i, String f, String m, String l, int a, String y, String c, double g) {
idNumber = i;
firstName = f;
middleName = m;
lastName = l;
age = a;
yearLevel = y;
course = c;
gwa = g;
}
public int getIdNumber() {
return idNumber;
}
public String getFirstName() {
return firstName;
}
public String getMiddleName() {
return middleName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getYearLevel() {
return yearLevel;
}
public String getCourse() {
return course;
}
public double getGwa() {
return gwa;
}
public void setIdNumber(int idnumber) {
idNumber = idnumber;
}
public void setFirstName(String fName) {
firstName = fName;
}
public void setMiddleName(String mName) {
middleName= mName;
}
public void setLastNameName(String lName) {
lastName= lName;
}
public void setAge(int a) {
age = a;
}
public void setYearLevel(String yLevel) {
yearLevel = yLevel;
}
public void setCourse(String c) {
course = c;
}
public void setGwa(int gwa) {
gwa = gwa;
}
public String toString() {
return String.valueOf(System.out.printf("%-15s%-15s%-15d%-15d%n",
firstName, course , yearLevel ,gwa));
}
} // end of class
And I am trying to call it in this sort method, but I don't know how to reference it.
public static void sortFirstNameArray(String[] f){
for (int i = 0; i < f.length - 1; i++) {
for (int j = i + 1; j < f.length; j++) {
if (f[i].compareToIgnoreCase(f[j]) > 0) {
String temp = f[i];
f[i] = f[j];
f[j] = temp;
}
}
}
}
After the sorting is successfully done, I'll call it in a switch case statements that will be invoked once the user chooses a particular number. This part has 5 case statements (Name, Age, Course, General Weighted Average and the option to sort it all - I plan to add more student attributes if this works)
(I don't know if I should store this in another method and call it in the main method or just put it in the main method like that)
public RecordReference Process(RecordReference[] f, RecordReference[] a) {
// for loop?
for (int x = 0; x < f.length; x++) {
switch (choice) {
case 1:
System.out.println("Sorted array of first name: ");
sortFirstNameArray(f[x].getFirstName());
System.out.printf("%-15s%n", Arrays.toString(f));
break;
case 2:
System.out.println("Sorted array of age: ");
// invokes the age method
sortAgeArray(a[x].getAge());
System.out.printf("%-15s%n", Arrays.toString(a));
break;
}
}
}
If it is in another method, what param do I include when I call it in the main method?
I tried this but it doesn't work, I don't know what to do
System.out.print("Please choose what student attribute you want to
sort :");
choice = keyboard.nextInt();
// calling the process method here, but I receive syntax error
Process(f,a); // Here, I want to pass the sorted values back into the array but I get an error.
If you can help me out that would be great. Thank you in advance.
I'm just a first year student and I am eager to learn in solving this error.
It's good to see that you have attempted the problem yourself and corrected your question to make it clearer, because of that I am willing to help out.
I have tried to keep the solution to the problem as close to your solution as possible, so that you are able to understand it. There may be better ways of solving this problem but that is not the focus here.
First of all, let's create a class named BubbleSorter that will hold methods for sorting:
public class BubbleSorter
{
//Explicitly provide an empty constructor for good practice.
public BubbleSorter(){}
//Method that accepts a variable of type RecordReference[], sorts the
//Array based on the firstName variable within each RecordReference
//and returns a sorted RecordReference[].
public RecordReference[] SortByFirstName(RecordReference[] recordReferencesList)
{
for (int i = 0; i < recordReferencesList.length - 1; i++) {
for (int j = i + 1; j < recordReferencesList.length; j++) {
if (recordReferencesList[i].getFirstName().compareToIgnoreCase
(recordReferencesList[j].getFirstName()) > 0) {
RecordReference temp = recordReferencesList[i];
recordReferencesList[i] = recordReferencesList[j];
recordReferencesList[j] = temp;
}
}
}
return recordReferencesList;
}
}
That gives us a class that we can instantiate, where methods can be added to be used for sorting. I have added one of those methods which takes a RecordReference[] as a parameter and sorts the RecordReference[] based on the firstName class variable within each RecordReference. You will need to add more of your own methods for sorting other class variables.
Now for the main class:
class Main {
public static void main(String[] args) {
//Get a mock array from the GetMockArray() function.
RecordReference[] refArray = GetMockArray();
//Instantiate an instance of BubbleSorter.
BubbleSorter sorter = new BubbleSorter();
//Invoke the SortByFirstName method contained within the BubbleSorter
//and store the sorted array in a variable of type RecordReference[] named
//sortedResult.
RecordReference[] sortedResult = sorter.SortByFirstName(refArray);
//Print out the results in the sorted array to check if they are in the correct
//order.
//This for loop is not required and is just so that we can see within the
//console what order the objects in the sortedResult are in.
for(int i = 0; i < sortedResult.length; i++)
{
System.out.println(sortedResult[i].getFirstName());
}
}
public static RecordReference[] GetMockArray()
{
//Instantiate a few RecordReferences with a different parameter for
//the firstName in each reference.
RecordReference ref1 = new RecordReference(0, "Ada", "Test", "Test", 22, "First",
"Computer Science", 1.0f);
RecordReference ref2 = new RecordReference(0, "Bob", "Test", "Test", 22, "First",
"Computer Science", 1.0f);
RecordReference ref3 = new RecordReference(0, "David", "Test", "Test", 22,
"First", "Computer Science", 1.0f);
//Create a variable of type RecordReference[] and add the RecordReferences
//Instantiated above in the wrong order alphabetically (Based on their firstName)
//class variables.
RecordReference[] refArray = {
ref2, ref3, ref1
};
return refArray;
}
}
In the main class I have provided verbose comments to explain exactly what is happening. One thing I would like to point out is that I have added a method named GetMockArray(). This is just in place to provide a RecordReference[] for testing and you probably want to do that somewhere else of your choosing.
If anything is not clear or you need some more assistance then just comment on this answer and I will try to help you further.
Thanks.
I'm working on a project where I will tally a Student's choices and add them to a count array (still working on this part). For now, I'm trying to retrieve the choices that have been sent and added to a Student ArrayList in my Student class.
Student class:
public class Students {
private String name;
private ArrayList<Integer> choices = new ArrayList<Integer>();
public Students(){
name = " ";
}
public Students(String Name){
name = Name;
}
public void setName(String Name){
name = Name;
}
public String getName(){
return name;
}
public void addChoices(int Choices){
choices.add(Choices);
}
public ArrayList<Integer> getChoices(){
return choices;
}
Here is my main driver class:
public class P1Driver {
public static void main(String[] args) throws IOException{
ArrayList<Students> students = new ArrayList<Students>();
String[] choices = new String[100];
int[] count;
Scanner scan1 = new Scanner(new File("Choices.txt"));
Scanner scan2 = new Scanner(new File("EitherOr.csv"));
// Scan the first file.
int choicesIndex = 0;
while(scan1.hasNextLine()){
String line = scan1.nextLine();
choices[choicesIndex] = line;
choicesIndex++;
}
scan1.close();
// Scan the second file.
int studentIndex = 0;
while(scan2.hasNextLine()){
String line = scan2.nextLine();
String [] splits = line.split(",");
students.add(new Students(splits[0]));
for(int i = 1; i < splits.length; i++){
students.get(studentIndex).addChoices(Integer.parseInt(splits[i]));
}
studentIndex++;
}
scan2.close();
// Instantiate and add to the count array.
int countIndex = 0;
for(int i = 0; i < students.size(); i++){
if(students.get(i).getChoices(i) == -1){
}
}
The last part is where I am now. It's nowhere near done obviously (I'm right in the middle of it) but during my construction of a for loop to get the choices from the students, I'm getting an error that says, "The method getChoices() in the type Students is not applicable for the arguments (int)." Can someone explain what this means, where me error is, and possibly how to fix it? Thanks all.
getChoices(int i) is not a method you've defined.
if(students.get(i).getChoices(i) == -1){
}
getChoices() returns a list, so you can just use the get method on the list:
if(students.get(i).getChoices().get(i) == -1){
}
Alternatively, make a getChoice method:
public Integer getChoice(int i){
return choices.get(i);
}
Have you tried getChoices()[i] instead of getChoices(i)
I want to create an object named "Course", and get the information from the keyboard. The last attribute called the "pre", which means the prerequisite courses of this course. I want to input the whole information in one line and extract the information for each attribute. But I got the problem with"pre". I run the program and the output of course.pre is null. I do not know why. Here is my Course class code:
`import java.util.HashSet;
public class Course{
private String name;
private int isFall;
private int NumPre;
private HashSet<Course> pre;
public Course(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String setName (String n){
return name = n;
}
// 1 - fall 0 - both -1 - spring
public void setType(String isFall) {
if(isFall.equals("F") || isFall.equals("f")){
this.isFall = 1;
}else if(isFall.equals("S") || isFall.equals("s")){
this.isFall = -1;
}else if(isFall.equals("B") || isFall.equals("b")){
this.isFall = 0;
}
}
public int getType(){
return isFall;
}
public void SetNumPre(int n) {
this.NumPre = n;
}
public int getNumPre() {
return NumPre;
}
public void addPre(Course c) {
pre.add(c);
}
public HashSet<Course> getPre() {
return pre;
}
}
`
And here is my main method here:
import java.util.*;
public class TimeToGraduate {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
//System.out.print("Input first two integers here: ");
String globalInfo = scanner.nextLine();
String[] numOfCourse = globalInfo.split(" ");//[0] num of total course [1] max num per semester
int totalNum = Integer.parseInt(numOfCourse[0]);
int maxPre = Integer.parseInt(numOfCourse[1]);
Course courses[] = new Course[totalNum];
//System.out.print("Please input course list here: ");
String coursesList = scanner.nextLine();
String[] nameOfCourse = coursesList.split(" ");
for(int i = 0;i < totalNum; i++){
courses[i] = new Course(nameOfCourse[i]);
}
//System.out.print("Please input course info here: ");
for(int i = 0;i < totalNum; i++){
String courseInfo = scanner.nextLine();
String[] infoOfCourse = courseInfo.split(" ");
courses[i].setName(infoOfCourse[0]);
courses[i].setType(infoOfCourse[1]);
courses[i].SetNumPre(Integer.parseInt(infoOfCourse[2]));
if(courses[i].getNumPre() > 0){
for(int j = 3; j < 3+(courses[i].getNumPre()); j++){
for(int k = 0; k < totalNum; k++){
if(infoOfCourse[j] == courses[k].getName()){
courses[i].addPre(courses[k]);
}
}
}
}
}
scanner.close();
for(int m = 0; m < totalNum; m++){
System.out.print(courses[m].getName()+" ");
System.out.print(courses[m].getType()+" ");
System.out.print(courses[m].getNumPre()+" ");
System.out.print(courses[m].getPre()+" ");
System.out.println();
}
}
}
Notice that you did not initilize the pre attribute. That is why it is null.
It would be a good practise if you initilize the pre inside a constructor for the Course class. Otherwise, do it when you start filling the Course attributes.
Update:
Your constructor should be like this:
public Course() { this.pre = new HashSet()}
As you can see the constructor does not have any arguements, because you will be filling its attribute from the main function.
You can define a constructor with arguments too:
public Course(String name, HashSet<Course> pre)
{ this.name = name; this.pre = pre; }
But you will need to initilize pre and name when you call it from the main:
...
HashSet hs = new HashSet();
course[i] = new Course('course_name', hs);
....
Good evening everyone. I'm working on a piece of homework and I finally have it nearly complete. Currently, the only thing stopping compilation is a breakpoint error at line 42. Eclipse tells me that it is the variable "list" being uninitialized, however, i cant find where or why this is happening.
The program is for a homework assignment in beginning java. It is designed to import a list of names from a text file called names.txt, then be able to sort through them in an interface, and while the menu is yet to be added, I want to get compiled and make sure its working before I go changing things again.
import java.util.*;
import java.io.*;
public class Name {
private String givenName;
private int[] ranks = new int[11];
public static void main( String[] args ) {
List<Name> list = new ArrayList<Name>();
loadFile();
System.out.println( list.get( 0 ).getPop( 0 ) );
}
private static void loadFile() {
Scanner inputStream = null;
String fileName = "names.txt";
try {
inputStream = new Scanner( new File( fileName ) );
}
catch (FileNotFoundException e) {
System.out.println( "Error opening file named: " + fileName );
System.out.println( "Exiting..." );
}
while ( inputStream.hasNextLine() ) {
String line = inputStream.nextLine();
String[] tokens = new String[0];
String givenName = tokens[0];
int[] numList = new int[tokens.length - 1];
for ( int i = 1; i < tokens.length; i++ ) {
numList[i - 1] = Integer.parseInt( tokens[i].trim() );
}
list.add( new Name( givenName, numList ) );
}
}
// here we get the name for the
public Name(String name, int[] popularityRanks) {
givenName = name;
for ( int i = 0; i < 11; i++ ) {
ranks[i] = popularityRanks[i];
}
}
public String getName() {
return givenName;
}
public int getPop( int decade ) {
if ( decade >= 1 && decade <= 11 ) {
return ranks[decade];
}
else {
return -1;
}
}
public String getHistoLine( int decade ) {
String histoLine = ranks[decade] + ": ";
return histoLine;
}
public String getHistogram() {
String histogram = "";
for ( int i = 0; i < 11; i++ ) {
histogram += ranks[i] + ": " + this.getHistoLine( i ) + "\n";
}
return histogram;
}
}
In addition, I used lists to configure the variables, but now i am deeply regretting it as I feel far more comfortable with just multi-dimensional arrays. As this is homework related, I completely understand if no one wants to help me fix this second part and give me some code to change the lists to arrays.
I'm burnt out and just want it to compile at this point. Any pointers on where to go from here?
Your list declaration/initialization is in the main and you are trying to access it from loadFile method.
Just move you List<Name> list = new ArrayList<Name>(); as a class variable(put it right above the main) and your code should compile.
Eg:
public class Name {
private String givenName;
private int[] ranks = new int[11];
static List<Name> list = new ArrayList<Name>();
public static void main( String[] args ) {
loadFile();
......
Your list is not visible to the point your are going to add a Name object. Its better to pass the list as a reference to the loadFile() method, As like follows
loadFile(list); // Method call from the main().
And Load file
private static void loadFile(List list) {
// Your code
}
I've restructured your code fixing the scopes and the object definition. If your individual logic is correct(which I haven't really checked), you should get your desired output).
What you seem to have mixed up is the object and the calling client. The Name private class is a private object which is being instantiated in the main method. Subsequently the public methods of the Name object is being called upon.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Solution {
private static class Name{
private final int items = 11;
private String givenName;
private int[] ranks;
//Constructor
public Name(String name, int[] popularityRanks) {
givenName = name;
ranks = new int[items];
for (int i = 0; i < items; i++) {
ranks[i] = popularityRanks[i];
}
}
public String getName() {
return givenName;
}
public int getPop(int decade) {
if (decade >= 1 && decade <= items) {
return ranks[decade];
} else {
return -1;
}
}
public String getHistoLine(int decade) {
String histoLine = ranks[decade] + ": ";
return histoLine;
}
public String getHistogram() {
String histogram = "";
for (int i = 0; i < 11; i++) {
histogram += ranks[i] + ": " + this.getHistoLine(i) + "\n";
}
return histogram;
}
}
public static void main(String[] args) {
List<Name> list = loadFile();
System.out.println(list.get(0).getPop(0));
}
private static List<Name> loadFile() {
List<Name> list = new ArrayList<>();
Scanner inputStream = null;
String fileName = "names.txt";
try {
inputStream = new Scanner(new File(fileName));
} catch (FileNotFoundException e) {
System.out.println("Error opening file named: " + fileName);
System.out.println("Exiting...");
}
while (inputStream.hasNextLine()) {
String line = inputStream.nextLine();
String[] tokens = new String[0];
String givenName = tokens[0];
int[] numList = new int[tokens.length - 1];
for (int i = 1; i < tokens.length; i++) {
numList[i - 1] = Integer.parseInt(tokens[i].trim());
}
list.add(new Name(givenName, numList));
}
return list;
}
}
First of all, ill advise you declare your list outside main,
Second, you want to populate the list before calling getPop.
look where you have:
System.out.println(list.get(0).getPop(0));
At this point list.get(0) returns null since the list hasn't been populated yet...and from your code getPop(0) will return -1, so the line above basically doesn't mean anything at that point.
And as for converting the list to arrays to make it "multidimensional"....
First lists can also be "multidimensional", if u know how to declare them...e.g
List> list = new ArrayList();
is a 2d array list.
Second generic lists like the one above are way flexible and have huge advantages over arrays, for example they can be dynamically modified; you can change their size at runtime unlike arrays.
With that said, if you want to convert a list to an array you need the type of the list and it's size and then it's easy using the toArray() method...like this:
String[] array = list.toArray(new String[list.size()]);
I'm currently trying to iterate through an ArrayList and see if it contains the following numbers I input into the winners array. However, the ticket object won't allow me to utilize the .contains() method which is where I'm getting the error. Any idea on how to work around this?
int[] winners = new int[6];
for(int i = 0; i < winners.length; i++)
{
winners[i] = in.nextInt();
}
in.close();
Scanner scan = new Scanner(file);
ArrayList<Ticket> info = new ArrayList<Ticket>();
for(int i = 0; i < lim; i++)
{
String name = scan.nextLine();
String num = scan.nextLine();
String[] t = num.split(" ");
int[] tichold = new int[t.length];
for(int j = 0; j < t.length; j++)
{
tichold[j] = Integer.parseInt(t[j]);
}
Ticket ticket = new Ticket(name, tichold);
info.add(ticket);
}
**for(Ticket t : info)
{
if(t.contains(winners))
{
System.out.println("Yes");
}
}**
scan.close();
}
**public static class Ticket
{
public String name;
public int[] tarray;
public Ticket(String name, int[] tarray)
{
this.name = name;
this.tarray = tarray;
}**
You can't use a method that doesn't exist for that class. Since you don't have contains defined for Ticket, I'm not surprised that it isn't working.
From inference, winners is an int[]. In that case, you'd define a new method contains inside of Ticket.
public boolean contains(int[] winningNumbers) {
// logic here
}
Depending on how the winning numbers for a given ticket are stored, and given how you define different conditions of winning, you'd handle your logic here.
If they're stored as an array and you want an exact match, then you can use Arrays.equals for that.
public boolean contains(int[] winningNumbers) {
return Arrays.equals(numbers, winningNumbers);
}
Try this Ticket class with and added contains method:
public class Ticket {
public String name;
public int[] tarray;
public Ticket(String name, int[] tarray)
{
this.name = name;
this.tarray = tarray;
}
public boolean contains(int[] winners) {
for (int i = 0; i < winners.length; i++) {
for (int j = 0; j < tarray.length; j++) {
if (winners[i] == tarray[j])
return true;
}
}
return false;
}
}