Store text file in non-String array - java

I am trying to store lines from a text file into an array that isn't a String array. The return type is supposed to be a GO-array ( have created another class named "GO" with constructors and get-/set-methods which I'll use in other parts of the code.)
int rad = 0;
GO [] list = new CD [rad];
public GO[] readFile(String filename) throws FileNotFoundException {
Scanner read = new Scanner (new File(filename));
while (read.hasNextLine()==true){
rad++;
read.nextLine();
} read.close();
read = new Scanner(new File(filename));
for (int i=0;i<list.length;i++){
//here the lines of the file should be stored in the "GO"array
// but the declaration cannot convert string to GO[]
list[i]=read.nextLine()

class GO<T>{
private T ref;
public GO(T ref) {
this.ref = ref;
}
}
you should change your GO class to use generics and you can add value to Go Array with this approach.
list[i] = new GO(read.nextLine());
by changing the class to generics . you can create an instance of Go class by passing any object to the constructor.

You'll need to parse the resulting String yourself and build a GO object out of it, which can be a separate method to keep things clean. Get the values of your object's variables and use your setters appropriately.
If your program is what's writing the file's contents, you'd be better off having GO implement Serializeable and saving/loading the state of the object itself instead of making text. If not, the above is your only option, really.

Related

Managing Files in java Read,Save,Write

I would like to write a general method readfile() to a class to use it on the subclasses to read all lines.
I have trouble with how to call methods from one class to another.
First, is it better to make void readfile() ?
or return a File?
Secondly, which is the way to reused from other classes?
Example of my code:
public class Reader{
Scanner myReader = new Scanner(myObj);
public void readFile(){
File myObj = new File("filename.txt");
Scanner myReader = new Scanner(myObj);
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
System.out.println(data);
}
}
}
public class ReadContentOfFile extends Reader{
public List<String> parseFile{
List<String> name = new ArrayList<>();
//how to get lines? as I have them, from
another method?
//for example If I want to get the
words,separated, by comma
return name;
}
}
public void Main(){
}
For example for each line of a file, how I get each element.
My problem is about how to get the data for another method, for another class.
First, is it better to make void readfile() ? or return a File?
Depends on what you want to do with the output, since you are printing the contents to console then you don't have to return the file and void is OK.
But if you wanted to use this file after you call the readFile method then you must return it or set it to class member.
Secondly, which is the way to reused from other classes?
make your method static, so you can access it without creating an object since it's just a utility and object is not important here.
public static void readFile(){
//..
}
then do
Reader.readFile()
Please, do not use Scanner to read a file, there are simpler and better options.
First, a File itself it's nothing but a reference and it won't contain any content
related to the file on system. So, you can consider to return a File object only if you may need some information from the file-system about privileges, existence, perform deleting actions or retrieving path information.
Usually when i write methods to read() or save() a file i make them void.
About how do you read data and access it, in java there are a lot of possibilities.
I'll show you one pretty straightforward:
List<String> lines = Files.readAllLines(Paths.get("filename.txt"), StandardCharsets.UTF_8);
And that's it but there are more options.

How to create objects in Java using data from each line from a CSV file

I have created a Class that has a constructor that takes a string line and after some processing of the data turns it into an object.
I need to feed data from a CSV one line at a time into the constructor to create an object for every line of the file. However from all my searching I cannot figure out how to create these objects as,from what I have learnt, to create object you have to name these objects. Is there a way to create an array of objects so I don't have to name each object? for example the first line would be like Object[0] and so on?
public class Object{
String Name, Example, Example2;
Object(String data){
//Data manipulation to get into Name Example and Example2 creating an
//object
}
public String getName{
return Name;
}
}
public class ObjectFeed{
//This is where I would open the file and feed it line by line into the
//object class
}
I should be able to use the getter methods i created for the Object class on any line number and it should get that information. I just do not understand how to feed data into Objects and create multiple objects.
I would do something like this:
public void createYourObjects() {
List<String> lines = // however you are reading lines from the CSV file
List<YourObject> objects = new ArrayList<>();
for(String line in lines) {
objects.add(methodB(line);
}
}
public YourObject createYourObjectFrom(String line) {
List<String> columns = line.spilt(",");
return new YourObject(columns.get(0), columns.get(1) ..... columns(n-1)); // where n is the size of the list n-1 is the index of the last item in the list
}
Its bit pseudocode-ish but I think it illustrates the basic idea. By using a separate method to construct your object you separate the concern, isolating the creation of your list of objects from the structure of the CSV file.
It also gives you a place to provide any error or special case handling you may need.
In a real world scenario you may need to handle different types of data, translating from String to say int, and also when a column is empty.
In the case where a column is empty you will get a smaller list of columns, and you will have to handle this.
If the data is coming from a CSV, each cell should be separated by a comma, so you should be able to take the input string data and split it.
This could be done like:
String[] csvList = data.split(",");
You can then assign each element of csvList as one of your object's properties, and loop through all of its elements to produce a list of your objects.
List<YourObject> objects = new List<YourObject>();
// increment i by the how many properties YourObject has
for (int i = 0; i < csvList.length; i += 2) {
YourObject obj = new YourObject();
obj.FirstProperty = csvList[i];
obj.SecondProperty = csvList[i+1];
...
objects.add(obj);
}

Array reference type in a method

I have been given a starting code to work on a project, however I am confused about the following code and cant seem to find any examples online!
public static Entity[][] read(){ ... }
How can I handle this Entity to add new entries to an array, and then how can I return this?
The following constructor is invoked by a different class.
public World() {
aWorld = new Entity[SIZE][SIZE];
int r;
int c;
for (r = 0; r < SIZE; r++) {
for (c = 0; c < SIZE; c++) {
aWorld[r][c] = null;
}
}
aWorld = FileInitialization.read();
}
I feel it would be much simpler if the array was just a parameter or if it were something like:
public static int[][] read(){ ... }
UPDATE:
The goal is to read from a file in the method read() and then assign the an entity to the correct location based on the location in the file. But I am not able to assign since the data types would be incompatible, Required is Entity, but I want to be able to set it to an int, char or String.
To add to an array of objects, you do exactly what you would with an array of primitives (e.g. ints), you just use Entitys. So if you want to add something to aWorld you use
aWorld[r][c] = new Entity(...); //with provided constructor's parameters
// or
aWorld[r][c] = existing_Entity; //for an Entity variable you already have
When you're done adding, you simply return the array aWorld.
If FileInitialization's static read() is going to return Entity[][], that's an entity array by itself. It means that you shouldn't iterate aWorld, rather assign the return value to it directly like
aWorld = FileInitialization.read();
Inside the read(), use that for loop you've made in the constructor and add a new Entity object as noted by Linus
Alright I would like to say thanks to all of you here as I was set on the right direction. But I would like to share my answer which should be simple and hopefully make someones life easier in the future.
To initialize the array of objects just do it as you would initialize any other array, in this case:
Entity[][] reference_name = new Entity[SIZE][SIZE];
To return this value, simply return the reference:
return reference_name;
Now the part where you actually modify an entry into your array.
Lets say you have something like
public static void Entity[][] read() { .. }
you need to create a class file Entity.java (same name as the array type being passed)
In this case it would look something like this:
public class Entity {
private char appearance;
public Entity(char anAppearance) {
appearance = anAppearance;
}
now to give this array an entry do something like this:
reference_name[0][0] = new Entity('X');
alright and in case you are wondering how to display this just add an accesor method to class Entity.
public char getAppearance() {
return(appearance);
}
and to output:
System.out.println(reference_name[0][0].getAppearance(); );

Java; null pointer on newly created array with user-defined length

So, right after the public class declaration, I've declared an array as follows:
public String[] accept;
From here then, I'm looking to take user input to see how long this array should be - and following this, we'd enter into a loop to populate the array with Strings. I put the following into a method;
if (scanner.hasNextInt()) {
wcount = scanner.nextInt();
//create the array.
String accept[] = new String[wcount];
}
System.out.println(accept.length);
But unfortunately, no nice. Java returns with;
Exception in thread "main" java.lang.NullPointerException
Obviously, attempting to go straight into a for loop to populate the array, will also give the same results. At first glance, I'm assuming this has something to do with it being initialised as a public array outside of the method itself - but I'm honestly not too sure. Can anyone lend a hand on this?
You are declaring a new array in your if block, which is hiding your previously declared array. When the block exits, the variable goes out of scope and you get an NPE attempting to access the (unchanged) instance variable. Change your code to actually initialize your instance variable like so:
if (scanner.hasNextInt()) {
wcount = scanner.nextInt();
//create the array.
accept = new String[wcount];
}
System.out.println(accept.length);
You are recreating a new accept [] as local variable. Change your loop as below
if (scanner.hasNextInt()) {
wcount = scanner.nextInt();
//create the array.
accept = new String[wcount];
}
Change String accept[] to just accept within the if statement, you are redeclaring a new one within that scope, leaving the old one null.
String accept[] = new String[wcount];
declares a variable, and stores the reference to the new string array into it.
You probably want to use the previously declared variable instead. To do that, simply use assignment expression directly:
accept = new String[wcount];

Saving an ArrayList of various objects in an efficient way

I would like to know how to save an ArrayList of abstract Objects to a file.
So far I only save primitive types or ArrayLists of primitive types by converting them to a comma separated String and storing this with a buffered reader.
But now I have got an ArrayList of Game Elements, which have really different properties and Constructors, so my normal approach won't work. There has to be something nicer than storing each to a file or each type of Object to a file or add plenty of seperator levels.
How do I do this in a nice way?
Have a look at Serialization, there are plenty of tutorials out there so I am not going to post any code:
http://www.tutorialspoint.com/java/java_serialization.htm
You can not instantiate Abstract Objects so you will need a child class which extends it. Also Abstract class should implement Serialize. Then using ObjectOutputStream you can directly write ArrayList using writeObject() method.
Below is the sample application
public abstract class Parent implements Serializable {
public abstract String getValue(); //Just to show value persist
}
public class Child extends Parent {
String value = null;
Child(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
// No throws clause here
public static void main(String[] args) throws FileNotFoundException,
IOException, ClassNotFoundException {
//create Arraylist
ArrayList<Parent> parents = new ArrayList<Parent>();
parents.add(new Child("test"));
//store
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
new FileOutputStream("test.txt"));
objectOutputStream.writeObject(parents);
objectOutputStream.close();
//Read back
ObjectInputStream objectInputStream = new ObjectInputStream(
new FileInputStream("test.txt"));
ArrayList<Parent> readObjects = (ArrayList<Parent>)objectInputStream.readObject();
System.out.println(readObjects.get(0).getValue());
}
The answer could be two.
Depending on what is the usage of the file later.
ANS 1: It you want the object values to be saved temporarily in the file and reload it again from the file, then serialization is the best options.
ANS 2: If the file is output of the program and then you try the below
option#1: Start each line in the file with the unique object name
OBJECT1, blue, pink, yellow....
OBJECT2, rose, dairy, sunflower, cauliflower..
option#2 instead of the flat file(txt) you can use an apache poi framework to write
the object in more organised way.

Categories