Breakpoint errors in javaeclipse - java

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()]);

Related

(JAVA) cut array into statements and save it in objects of a new array?

I need a program that cuts an 1-dimensional array into a 2-dimensional array.
But: the 2nd-dimension must not be annother array, but new objects.
I have two inputs:
String Array 1 contains a full command-statement (including args and values)
String Array 2 contains all valid arg-Names
I want one output:
A String Array which contains the arg+value: All Elements of this Array are objects of the class "cuttedStatement"
These objects of the class "cuttedStatement" can have both:
(Argument + his value) OR (only Argument). So Argument with or without value are valid!
Look at the describing picture:
Here is my code for the CutterPrgm:
import java.util.*;
public class Main {
public static void main(String[] args) {
String[] statement = {"-in", "FILENAME", "-out", "FILENAME" , "-keep" , "-typ", ".avi", "-status"};
String[] validArgs = {"-in", "-out", "-keep", "-typ", "-status"};
ArrayList<CuttedStatement> cuttedOutputList = new ArrayList<>();
for (int i = 0; i < statement.length; i++) {
boolean contains = Arrays.asList(validArgs).contains(statement[i+1]);
if(contains) {
CuttedStatement obj[i] = new CuttedStatement(statement[i]);
cuttedOutputList.add(obj);
}else {
CuttedStatement obj[i] = new CuttedStatement(statement[i],statement[i+1]);
cuttedOutputList.add(obj);
}
}
}
}
this is my CuttedStatement-class:
public class CuttedStatement {
String argument;
String value;
boolean hasValue;
public CuttedStatement(String argument) {
this.argument = argument;
this.hasValue = false;
}
public CuttedStatement(String argument, String value) {
this.argument = argument;
this.value = value;
this.hasValue = true;
}
}
So now my question: As you might guess, the program doesn't work.
My first Problem is the "obj[i]" object. I wanted to create a new "obj" with index=i every new iteration so that you have: Array = {obj1, obj2, obj3, obj4, etc...}. This looks not to work.
Maybe you know a solution for me or have some tips. I hope so. Thank you very much for help, every help is welcome!!! :D
public class Main {
public static void main(String[] args) {
String[] statement = {"-in", "FILENAME", "-out", "FILENAME", "-keep", "-typ", ".avi", "-status"};
String[] validArgs = {"-in", "-out", "-keep", "-typ", "-status"};
ArrayList<CutStatement> cuttedOutputList = new ArrayList<>();
for (int i = 0; i < statement.length; i++) {
// do not use Arrays.asList() here. It will create a List instance in each iteration
// not sure that stream is the best solution though
int i_temp = i; // for lambda in stream
boolean contains = true;
if (i != statement.length - 1) { // if it is not the last element
contains = Arrays.stream(validArgs).anyMatch(s -> s.equals(statement[i_temp + 1]));
}
if (contains) {
// just do not use `[i]` here
CutStatement obj = new CutStatement(statement[i]);
cuttedOutputList.add(obj);
} else {
CutStatement obj = new CutStatement(statement[i], statement[i + 1]);
cuttedOutputList.add(obj);
i++; // increase i because we added two values from `statement`
}
}
System.out.println(cuttedOutputList);
}
}
class CutStatement {
private String argument;
private String value;
private boolean hasValue;
public CutStatement(String argument) {
this.argument = argument;
this.hasValue = false;
}
public CutStatement(String argument, String value) {
this.argument = argument;
this.value = value;
this.hasValue = true;
}
#Override
public String toString() {
if (hasValue) {
return "(" + argument + " = " + value + ")";
} else {
return "(" + argument + ")";
}
}
}
This program outputs
[(-in = FILENAME), (-out = FILENAME), (-keep), (-typ = .avi), (-status)]
I have little modified your logic. Here Map will contain what u require. Play with map for your final output.
String[] statement = { "-in", "FILENAME", "-out", "FILENAME", "-keep", "-typ", ".avi", "-status" };
String[] validArgs = { "-in", "-out", "-keep", "-typ", "-status" };
Map<String, String> m = new HashMap<String, String>();
String key = null;
for (int i = 0; i < statement.length; i++) {
boolean contains = false;
if(i + 1<statement.length){
contains = Arrays.asList(validArgs).contains(statement[i + 1]);
}
if (contains) {
m.put(key, statement[i]);
} else {
key = statement[i];
m.put(key, "");
}
}

How to increase size of array [a][b] every time I call a method?

public static int arraysize=1;
public String namabuku;
public String penulis;
public String Kategori;
public String buku[][]=new String[arraysize][3];
public static int a=0;
public void isiData(String kategori, String buku, String penulis){
this.buku[a][0]=kategori;
this.buku[a][1]=buku;
this.buku[a][2]=penulis;
arraysize++;
a++;
}
Hi guys I tried to increase my array length every time I call a method named "isiData", but it didn't work. I already checked the increment, but nothing wrong with it. Is there any way to increase its length every time I use the method? I want to make a simple way to input book, category, and its author using array.
You cannot increase the size of array.
There are 3 approaches to solve this problem:
Use ArrayList as suggested by others.
You can create another temp array of size one greater than the previous array and then copy the temp array to already created array.
You can use the copyOf(array, size) function of Arrays in Java
For example:
previousArray = Arrays.copyOf(previousArray , arraysize + 1);
arraysize += 1
Just try this Approach:
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
/**
*
* #author Maverick
*/
public class Buku {
public static int arraysize;
public String namabuku;
public String penulis;
public String Kategori;
public List<List<String>> bukuList = new ArrayList<List<String>>();
public static void main(String[] args) {
Buku n = new Buku();
for (int i = 0; i < 5; i++) {
n.isiData("ab" + i, "cd" + i, "ef" + i);
}
n.arraysize = n.bukuList.size();
for (int i = 0; i < n.bukuList.size(); i++) {
System.out.println(n.bukuList.get(i).toString());
}
}
public void isiData(String kategori, String buku, String penulis) {
bukuList.add(Arrays.asList(kategori, buku, penulis));
}
}
Output:
[ab0, cd0, ef0]
[ab1, cd1, ef1]
[ab2, cd2, ef2]
[ab3, cd3, ef3]
[ab4, cd4, ef4]
You have to call new array to change the size of an array. I assume this is an exercise to practice using an array, so I'm going to avoid the classes like Arrays and System in the isiData method. You should look at those classes though.
So something like this:
public class BukuTest
{
public String namabuku;
public String penulis;
public String Kategori;
public String buku[][] = new String[ 0 ][ 3 ];
public void isiData( String kategori, String buku, String penulis )
{
String[][] temp = this.buku;
final int len = temp.length;
this.buku = new String[ len + 1 ][];
for( int i = 0; i < len; i++ )
this.buku[i] = temp[i];
this.buku[len] = new String[ 3 ];
this.buku[len][0] = kategori;
this.buku[len][1] = buku;
this.buku[len][2] = penulis;
// not needed
// arraysize++;
// a++;
}
public static void main(String[] args) {
BukuTest b = new BukuTest();
b.isiData( "test1", "test2", "test3" );
b.isiData( "test4", "test5", "test6" );
b.isiData( "test7", "test8", "test9" );
System.out.println(b);
}
#Override
public String toString()
{
return "BukuTest{" + "namabuku=" + namabuku + ", penulis=" + penulis +
", Kategori=" + Kategori + ", buku=" +
Arrays.deepToString(buku) + '}';
}
}
Using an ArrayList is definitely the way to go here as others have commented and displayed but, if you are absolutely bent on using a Two Dimensional String Array then this can be done with a custom method conveniently named redimPreserve() as I have shown below.
As #Jdman1699 had mentioned in his comment under your post, this is a very inefficient way of doing this sort of thing especially for larger arrays but since you asked, here is how it can be done:
// YOUR METHOD:
public int arraysize = 1;
public String[][] buku = new String[arraysize][3];
public void isiData(String kategori, String buka, String penulis){
// I have renamed the buku argument for this method to buka
// since you can not have a parameter variable named the
// same as a Class Global variable.
buku = redimPreserve(buku, arraysize, 3);
buku[arraysize-1][0] = kategori;
buku[arraysize-1][1] = buka;
buku[arraysize-1][2] = penulis;
arraysize++;
}
// THE redimPreserve() METHOD:
public static String[][] redimPreserve(String[][] yourArray, int newRowSize, int... newColSize) {
int newCol = 0;
if (newColSize.length != 0) { newCol = newColSize[0]; }
// The first row of your supplied 2D array will always establish
// the number of columns that will be contained within the entire
// scope of the array. Any column value passed to this method
// after the first row has been established is simply ignored.
if (newRowSize > 1 && yourArray.length != 0) { newCol = yourArray[0].length; }
if (newCol == 0 && newRowSize <= 1) {
throw new IllegalArgumentException("\nredimPreserve() Method Error!\n"
+ "No Column dimension provided for 2D Array!\n");
}
if (newCol > 0 && newRowSize < 1 && yourArray.length != 0) {
throw new IllegalArgumentException("\nredimPreserve() Method Error!\n"
+ "No Row dimension provided for 2D Array!\n");
}
String[][] tmp = new String[newRowSize][newCol];
if (yourArray.length != 0) {
for(int i = 0; i < yourArray.length; i++) {
System.arraycopy(yourArray[i], 0, tmp[i], 0, yourArray[i].length);
}
}
return tmp;
}

Why is my class variable rewriting itself after an unrelated method runs?

So I'm writing a basic MasterMind game that is... mostly functional. However, its exhibiting odd behavior and I'm unsure why.
The idea is that what defines a Code and its behavior is one file, the gameplay is another, and the Main just creates a new game and starts playing. When I initialize the game, the computer creates a new random string of 4 (the "secret code"), as expected; but then once I get input for the User guess, it seems to rewrite the secret code into whatever I've input. Further, my methods for evaluating matches don't work at all, but considering that the secret code keeps changing means that it's not being set to begin with, and I'm unsure why.
All three classes below. Why is my class variable in Game not setting properly and accessible to the other methods?
Main.java
class Main {
public static void main(String[] args) {
Game newGame = new Game();
newGame.play();
}
}
Code.java
import java.util.Random;
import java.util.HashMap;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Set;
import java.lang.Math;
import java.lang.StringBuilder;
class Code {
private static HashMap<String,String> PEGS;
private static ArrayList<String> pegStrings;
protected static String secretCodeString;
public static void main(String[] args) {
}
public Code(String input){
this.secretCodeString = input;
}
public Code(){
randomize();
}
//literally just creates the peghash
public static void setPegs(){
PEGS = new HashMap<String,String>();
PEGS.put("C","c");
PEGS.put("Y","y");
PEGS.put("R","r");
PEGS.put("P","p");
PEGS.put("O","o");
PEGS.put("G","g");
}
//turns the pegs ito something randomize can use
public static ArrayList<String> makePegArray(){
setPegs();
pegStrings = new ArrayList<String>();
Collection<String> pegValues = PEGS.values();
Object[] pegObjects = pegValues.toArray();
for (int i = 0; i < pegObjects.length; i++){
pegStrings.add(pegObjects[i].toString());
}
return pegStrings;
}
// sets Class Variable secretCode to a four letter combination
public static Code randomize(){
secretCodeString = new String();
Random rand = new Random();
int randIndex = rand.nextInt(makePegArray().size());
for (int i = 0; i < 4; i++){
randIndex = rand.nextInt(makePegArray().size());
secretCodeString = secretCodeString.concat(makePegArray().get(randIndex));
}
Code secretCode = parse(secretCodeString);
return secretCode;
}
public static Code parse(String input) {
setPegs();
makePegArray();
String[] letters = input.split("");
StringBuilder sb = new StringBuilder();
for (String letter : letters) {
if (pegStrings.contains(letter)) {
sb.append(letter);
} else {
System.out.println(letter);
throw new RuntimeException();
}
}
String pegListString = sb.toString();
Code parsedCode = new Code(pegListString);
//System.out.println(parsedCode);
return parsedCode;
}
public int countExactMatches(Code guess){
String guessString = guess.secretCodeString;
int exactMatches = 0;
String[] guessArray = guessString.split("");
String[] winningCodeArray = (this.secretCodeString).split("");
for(int i = 0; i < 4; i++){
if(guessArray[i] == winningCodeArray[i]){
exactMatches++;
}
}
return exactMatches;
}
public int countNearMatches(Code guess) {
String guessString= guess.secretCodeString;
HashMap<String,Integer> guessCount = new HashMap<String,Integer>();
HashMap<String,Integer> secretCodeCount = new HashMap<String,Integer>();
Set<String> codeKeys = guessCount.keySet();
int matches = 0;
int keys = guessCount.keySet().size();
String[] keyArray = new String[keys];
for(int i = 0; i < guessString.length(); i++) {
//removes character from string
String codeCharacter = String.valueOf(guessString.charAt(i));
String guessShort = guessString.replace(codeCharacter,"");
//counts instances of said character
int count = guessString.length() - guessShort.length();
guessCount.put(codeCharacter, count);
}
for(int i = 0; i < secretCodeString.length(); i++) {
//removes character from string
String winningString = this.secretCodeString;
String winningCodeCharacter = String.valueOf(winningString.charAt(i));
String winningCodeShort = guessString.replace(winningCodeCharacter,"");
//counts instances of said character
int count = winningString.length() - winningCodeShort.length();
secretCodeCount.put(winningCodeCharacter, count);
}
for (int i = 0; i < keys; i++) {
codeKeys.toArray(keyArray);
String keyString = keyArray[i];
if (secretCodeCount.containsKey(keyString)) {
matches += Math.min(secretCodeCount.get(keyString), guessCount.get(keyString));
}
}
int nearMatches = matches - countExactMatches(guess);
return nearMatches;
}
}
Game.java
import java.util.Scanner;
class Game {
protected static Code winningCode;
public static void main(String[] args){
}
public Game(){
winningCode = new Code();
}
protected static Code getGuess() {
Scanner userInput = new Scanner(System.in);
int count = 0;
int maxTries = 5;
while(true){
try {
String codeToParse = userInput.next();
Code guess = Code.parse(codeToParse);
return guess;
} catch(RuntimeException notACode) {
System.out.println("That's not a valid peg. You have " + (maxTries - count) + " tries left.");
if (++count == maxTries) throw notACode;
}
}
}
protected static void displayMatches(Code guess){
int nearMatches = winningCode.countNearMatches(guess);
int exactMatches = winningCode.countExactMatches(guess);
System.out.println("You have " + exactMatches + " exact matches and " + nearMatches + " near matches.");
}
protected static void play(){
int turnCount = 0;
int maxTurns = 10;
System.out.println("Greetings. Pick your code of four from Y,O,G,P,C,R.");
while(true){
Code guess = getGuess();
displayMatches(guess);
if (guess == winningCode) {
System.out.print("You win!!");
break;
} else if (++turnCount == maxTurns) {
System.out.print("You lose!!");
break;
}
}
}
}
On every guess, you call Code.parse, Code.parse creates a new Code (new Code(pegListString);) and that constructor sets the secretCodeString and because that's static, all instances of Code share the same variable. You need to avoid mutable static members.
Another tip is to either have a method return a value, or mutate state (of either its input, or its own instance, this), but avoid doing both.
"Why is my class variable rewriting itself after an unrelated method runs?"
Because, actually, it is not unrelated. The "mess" that you have created by declaring variables and methods as static has lead to unwanted coupling between different parts of your code.
It is difficult to say what the correct solution is here because your code has gotten so confused by the rewrites that it is hard to discern the original "design intent".
My advice would be to start again. You now should have a clearer idea of what functionality is required. What you need to do is to redo the object design so that each class has a clear purpose. (The Main and Game classes make sense, but Code seems to be a mashup of functionality and state that has no coherent purpose.)

How to store an array of String as an enumeration type

I have made two classes, one is called Card, and the other is Pack.
The Card class has the following attributes :
private String Name;
private int Magic;
private int Cunning;
private int Courage;
private int Wisdom;
private int Temper;
In the Pack class, I have made a file reader methods that read a file on my PC and store each line of it as a string array. So for example this is a part of the text (not code):
Pansy_Parkinson
42
21
18
19
9
Dean_Thomas
40
10
35
22
4
My String array[] stores each line as a different index.
What I want to do, is to convert this String array to array of type Card.
It should store in each index a card with the 6 attributes..
So I suppose I will need to have a method to convert it, and I will have my new 2D Card array based on the previous text this way:
Card [][] ArrayOfCards = new Card [1][5];
Please, any idea how I can do this?
..........................................................
..........................................................
Thank you very much everyone for your valuable helps!
I tried all codes and they seemed great! but I don't know why it's showing me errors either in my main or the methods themselves..
Here is my FileReader class!
import java.io.File;
import java.util.Arrays;
import java.io.*; //To deal with exceptions
import java.util.*;
import java.util.Scanner;
import java.util.ArrayList;
public class ReadFile {
private Scanner x;
private String Path;
public ReadFile (String ThePath){
Path = ThePath;
}
public String[] openFile() throws IOException /*To throw any errors up the line*/
{
FileReader FR = new FileReader(Path);
BufferedReader TextReader = new BufferedReader(FR);
int NoOfLines = readLines();
String[] TextData = new String[NoOfLines];
for (int i = 0; i < NoOfLines; i++)
TextData[i] = TextReader.readLine(); //Accesses the lines of text and stores them in the array
TextReader.close();
return TextData;
}
int readLines() throws IOException //Return the number of lines in the text
{
FileReader FR2 = new FileReader(Path);
BufferedReader BF = new BufferedReader(FR2);
String ALine;
int NoOfLines = 0;
while ((ALine = BF.readLine()) != null)//Read each line of text & stop when a null value's reached
NoOfLines++;
BF.close();
return NoOfLines;
}
}
And I have just read it yet on main as like this:
public static void main(String[] args) {
// TODO code application logic here
String FileName = "C:/Users/Anwar/Desktop/Potter.txt"; //Path of the file on my PC
try {
ReadFile File = new ReadFile(FileName);
String[] ArrayLines = File.openFile();
for(int i = 0; i < ArrayLines.length; i++)
System.out.println(ArrayLines[i]);
}
catch (IOException e) /*Defiend object of type IOException*/ {
System.out.println(e.getMessage());
}}
Anyone can help me in this?
Because you have a c# tag with your question I decided to give a c# example, which you should be able to convert over to java fairly easily.
Essentially I've created a Card class which has a constructor that accepts the 6 stats about the card. I've kept the fields private as this is how they are in your Question.
I've create a for loop that runs through each of the items in the array, effectively taking 6 items at a time and passing them through to the Card constructor. We're then adding this card to our List of Cards.
I also threw in a quick ToInt() extension to tidy up the Card instantiation.
There are going to be better ways of doing this, but this solves the problem you have presented us with. There is also no error handling in this example.
class Program
{
static void Main(string[] args)
{
var rawData = new string[]{
"Pansy_Parkinson",
"42",
"21",
"18",
"19",
"9",
"Dean_Thomas",
"40",
"10",
"35",
"22",
"4"
};
var Cards = new List<Card>();
for(int i = 0; i < rawData.Length; i+=6)
{
var card = new Card(rawData[0 + i], rawData[1 + i].ToInt(), rawData[2 + i].ToInt(), rawData[3 + i].ToInt(), rawData[4 + i].ToInt(), rawData[5 + i].ToInt());
Cards.Add(card);
}
}
}
public static class StringExtensions
{
public static int ToInt(this string item)
{
return Convert.ToInt32(item);
}
}
public class Card
{
private string Name;
private int Magic;
private int Cunning;
private int Courage;
private int Wisdom;
private int Temper;
public Card(string name, int magic, int cunning, int courage, int wisdom, int temper)
{
Name = name;
Magic = magic;
Cunning = cunning;
Courage = courage;
Wisdom = wisdom;
Temper = temper;
}
}
Maybe try to od it like that:
Create constructor for Card with param String array[][] and which will be the array created from text file and second param which will be the int number that will say where to search for the data for constructor
the constructor should work like this:
Card(String[][] array, int numberForConstructor){
this.name = array[numberForConstructor][0];
this.magic = array[numberForConstructor][1];
this.cunning = array[numberForConstructor][2];
this.courage = array[numberForConstructor][3];
this.temper = array[numberForConstructor][4];
}
then you can use this constructor to put new Card objects to Array, List or anything you want
You should create getter/setter for your class Card, then you can use this function. I don't know which language you use (c# or java) so you will have to adjust the solution bellow.
public class Pack
{
public List<Card> cards = new List<Card>();
public Pack(string filename)
{
// Your parsing function
while ((line = readLine() != null)
{
Card c = new Card();
c.setName(line);
c.setMagic(Convert.ToInt32(readLine());
c.setCunning(Convert.ToInt32(readLine());
c.setCourage(Convert.ToInt32(readLine());
c.setWisdom(Convert.ToInt32(readLine());
c.setTemper(Convert.ToInt32(readLine());
cards.add(c);
}
}
}
Then you to create a new Pack just do the following
Pack p = new Pack("cards.txt");
p.cards[0].getName();
It seams that your input array has one card parameter per line. So I think you are simply looking for something like this:
public static Card[] convert(String[] arr){
if(arr.length % 6 != 0){
System.out.println("error in data");
return null;
}
Card[] res = new Card[arr.length / 6];
for(int i = 0; i < res.length; i++){
String Name = arr[(i * 6) + 0];
int Magic = Integer.parseInt(arr[(i * 6) + 1]);
int Cunning = Integer.parseInt(arr[(i * 6) + 2]);
int Courage = Integer.parseInt(arr[(i * 6) + 3]);
int Wisdom = Integer.parseInt(arr[(i * 6) + 4]);
int Temper = Integer.parseInt(arr[(i * 6) + 5]);
res[i] = new Card(Name, Magic, Cunning, Courage, Wisdom, Temper);
}
return res;
}
This can work:
public Card ConvertArrayToCard(string[] array)
{
Card card = new Card;
card.Name = array[0];
card.Magic= array[1];
card.Cunning= array[2];
card.Courage= array[3];
card.Wisdom= array[4];
card.Temper= array[5];
}
Quite a few answers.. Here is another one.
Your class;
public class Pack
{
public string Name { get; set; }
public int Magic { get; set; }
public int Cunning { get; set; }
public int Courage { get; set; }
public int Wisdom { get; set; }
public int Temper { get; set; }
}
Then the logic. There is some built in defensive coding mechanism in this. I will let you figure that out.
var lines = File.ReadAllLines(#"C:\temp2.txt");
List<Pack> mypack = new List<Pack>();
Pack member = null;
int count = 0;
foreach (var line in lines)
{
int val;
count = (!int.TryParse(line, out val)) ? 0 : count + 1;
switch (count)
{
case 0:
member = new Pack() { Name = line.Trim() };
break;
case 1:
member.Magic = val;
break;
case 2:
member.Cunning = val;
break;
case 3:
member.Courage = val;
break;
case 4:
member.Wisdom = val;
break;
case 5:
member.Temper = val;
mypack.Add(member);
break;
}
}
return mypack;

Data not transferring properly between classes; results in NullPointerException

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.

Categories

Resources