I got a task. The input of the Java Decathlon program is a CSV-like text file. The task is to output an XML file with all athletes in ascending order of their places, containing all the input data plus total score and the place in the competition (in case of equal scores, athletes must share the places, e.g. 3-4 and 3-4 instead of 3 and 4)
This is my cvs file:
Jana Kari;12.61;5.00;9.22;1.50;60.39;16.43;21.60;2.60;35.81;5.25.72
Eva Narun;13.04;4.53;7.79;1.55;64.72;18.74;24.20;2.40;28.20;6.50.76
Maja Hope;13.75;4.84;10.12;1.50;68.44;19.18;30.85;2.80;33.88;6.22.75
Kirke Kanda;13.43;4.35;8.64;1.50;66.06;19.05;24.89;2.20;33.48;6.51.01
I got these constants for each decathlon event
double[] A = new double[]{25.4347,0.14354,51.39,0.8465,1.53775,5.74352,12.91,0.2797,10.14,0.03768};
double[] B = new double[]{18,220,1.5,75,82,28.5,4,100,7,480};
double[] C = new double[]{1.81,1.4,1.05,1.42,1.81,1.92,1.1,1.35,1.08,1.85};
Formula for points is
Points = INT(A(B — P)^C) for track events (faster time produces a better score)
Points = INT(A(P — B)^C) for field events (greater distance or height produces a better score)
"P" is persons records (from cvs). I dont really understand how to read properly from file that it would allow me to do calculations with numbers only. Should i use two dimensional array for cvs file ? Its very confusing and im stuck.
EDIT
Well i believe for outputing later to xml file one dimensional array is better. The point of my task is code simplicity, but CVS file may be expanded to N lines so i never know how much rows it will have. I want to use number array in this code:
double[] A = new double[]{25.4347,0.14354,51.39,0.8465,1.53775,5.74352,12.91,0.2797,10.14,0.03768};
double[] B = new double[]{18,220,1.5,75,82,28.5,4,100,7,480};
double[] C = new double[]{1.81,1.4,1.05,1.42,1.81,1.92,1.1,1.35,1.08,1.85};
double PTS;
double finalscore;
for (int i = 0; i < P.length;i++ )
{
finalscore=0;
if (i == 0)
{
PTS = A[i]* Math.pow((P[i]-B[i]),C[i]);
}
else if (i == 4)
{
PTS = A[i]* Math.pow((P[i]-B[i]),C[i]);
}
else if (i == 5 || i == 9)
{
PTS = A[i]* Math.pow((P[i]-B[i]),C[i]);
}
else
{
PTS = A[i]* Math.pow((P[i]-B[i]),C[i]);
}
finalscore = finalscore + PTS;
}
System.out.println(finalscore);
}
}
Where P[] would be array first lane of number without name.
P.S it seems code above gives me result NaN when i use
double[] P = new double[]{12.61,5.00,9.22,1.50,60.39,16.43,21.60,2.60,35.81,5.272};
Yes, you have the right idea - you can use a two dimensional array. I would also recommend you create a class called Person, as this is Java programming and Java is object-oriented, but if you have not studied creating multiple classes yet, you can skip that bit and just do it with two arrays, one one-dimensional array for the names and one two-dimensional array for the numbers.
For the one-dimensional array approach
public class Person {
String name;
double[] scores;
int minutes;
int seconds;
int hundredths;
public Person(String line) {
String[] splitted = line.split(";");
name = splitted[0];
// now fill in the other fields
for(int i = 1; i < splitted.length - 1; i++) {
scores[i - 1] = Double.parseDouble(splitted[i]);
}
String times = splitted[splitted.length - 1].split("\\.");
minutes = Integer.parseInt(time[0]);
// etc. - fill in the rest
}
}
(Actually, this might be wrong, because I assumed most of the numbers are scores, but I guess they are really seconds and hundredths of a second. It doesn't really matter, unless you could have a time over one minute for those events.)
Then you need to have an array of Person objects in your other class - let's make it quite big so that it will be big enough hopefully:
Person[] array = new Person[10000];
Now have a loop, and whenever you read a line from the file you just call the constructor.
array[j] = new Person(line);
Nice approach, isn't it?
Related
String[] courseNames=new String[numbOfCourses];
Double[] courseCredits=new Double[numbOfCourses];
String[] gradeLetters= new String[numbOfCourses];
I asked the user to enter some course names,credits and letters and I put them in each array like:
courseNames[j]= keyboard.next();
courseCredits[j]=keyboard.nextDouble();
gradeLetters[j]=keyboard.next();
I expect the output to be like
Before:
course numb course name course credit course Grade
1 C 3.0 A
2 B 3.0 B
3 D 3.0 A
user input: 2
After:
course numb course name course credit course Grade
1 C 3.0 A
2 D 3.0 A
Firstly, I strongly encourage you to use some kind of List since it will be much easier to achieve your desired effect.
To "delete" an item from the array you could create a method similar to this:
void deleteCourseAtIndex(int index) {
courseNames[index]= null;
courseCredits[index]= null;
gradeLetters[index]= null;
}
And then when you are doing your printf()'s to display the content of the arrays:
for (int i = 0; i < courseNames.length; i++) {
if (courseNames[i] != null)
//printf() with whatever formatting you have
}
To add a new course, you would have to have enough indices in your arrays to store a new course. This is why I would advise you to use a List. Nonetheless:
//This method adds course info to the arrays and returns a boolean whether it was successfully added
//Precondition: all arrays are the same length
boolean addCourse(String[] cNames, double[] cCredits, String[] gLetters) {
boolean added = false;
for (int i = 0; i < courseNames.length; i++) {
if (courseNames[i] == null) {
courseNames[i]= cNames;
courseCredits[i]= cCredits;
gradeLetters[i]= gLetters;
added = true;
}
}
return added;
}
With a List, you don't have to deal with the issue of running out of space because they don't have a fixed size when you initialize them. To do this with Lists, try something like this:
ArrayList<String> courseNames= new ArrayList<String>();
ArrayList<Double> courseCredits = new ArrayList<Double>();
ArrayList<String> gradeLetters = new ArrayList<String>();
Note that I used Double instead of double because double is a primitive and ArrayLists can't use primitives. Use the wrapper classes Integer, Double etc. when using Lists.
Now when you accept keyboard input:
courseNames.add(keyboard.next());
courseCredits.add(keyboard.nextDouble());
gradeLetters.add(keyboard.next());
And you don't even need to loop through each index!
Even better, you could make a completely new class called Course (as Andreas suggested) and make an ArrayList.
So I'm working on a program which is supposed to randomly put people in 6 rooms (final input is the list of rooms with who is in each room). So I figured out how to do all that.
//this is the main sorting sequence:
for (int srtM = 0; srtM < Guys.length; srtM++) {
done = false;
People newMove = Guys[srtM]; //Guys is an array of People
while (!done) {
newMove.rndRoom(); //sets random number from 4 to 6
if (newMove.getRoom() == 4 && !room4.isFull()) {
room4.add(newMove); //adds person into the room4 object rList
done = true;
} else if (newMove.getRoom() == 5 && !room5.isFull()) {
room5.add(newMove);
done = true;
} else if (newMove.getRoom() == 6 && !room6.isFull()) {
room6.add(newMove);
done = true;
}
}
The problem now is that the code for reasons I don't completely understand (something with the way I wrote it here) is hardly random. It seems the same people are put into the same rooms almost every time I run the program. For example me, I'm almost always put by this program into room 6 together with another one friend (interestingly, we're both at the end of the Guys array). So how can I make it "truly" random? Or a lot more random than it is now?
Thanks in advance!
Forgot to mention that "rndRoom()" does indeed use the standard Random method (for 4-6) in the background:
public int rndRoom() {
if (this.gender == 'M') {
this.room = (rnd.nextInt((6 - 4) + 1)) + 4;
}
if (this.gender == 'F') {
this.room = (rnd.nextInt(((3 - 1) + 1))) + 1;
}
return this.room;
}
if you want it to be more random try doing something with the Random method, do something like this:
Random random = new Random();
for (int i = 0; i < 6; i++)
{
int roomChoice = random.nextInt(5) + 1;
roomChoice += 1;
}
of course this is not exactly the code you will want to use, this is just an example of how to use the Random method, change it to how you want to use it.
Also, the reason I did random.nextInt(5) + 1; is because if random.nextInt(5) + 1; gets you a random number from 0 to 5, so if you want a number from 1 to 6 you have to add 1, pretty self explanatory.
On another note, to get "truly" random is not as easy as it seems, when you generate a "random" number it will use something called Pseudo random number generation, this, is basically these programs produce endless strings of single-digit numbers, usually in base 10, known as the decimal system. When large samples of pseudo-random numbers are taken, each of the 10 digits in the set {0,1,2,3,4,5,6,7,8,9} occurs with equal frequency, even though they are not evenly distributed in the sequence.
There might be something wrong with code you didn't post.
I've build a working example with what your classes might be, and it is distributing pretty randomly:
http://pastebin.com/u8sZRxi6
OK so I figured out why the results don't seem very random. So the room sorter works based on an alphabetical people list of 18 guys. There are only 3 guy rooms (rooms 4, 5 and 6) So each guy has a 1 in 3 chance to be put in say, room 6. But each person could only possibly be in 2 of the 6 spots in each room (depending on where they are in the list).
The first two people for example, could each only be in either the first or second spot of each room. By "spot" I mean their place in the room list which is printed in the end. Me on the other hand am second last on the list, so at that point I could only be in either the last or second last spot of each room.
Sorry if it's confusing but I figured out this is the reason the generated room lists don't appear very random - it's because only the same few people could be put in each room spot every time. The lists are random though, it's just the order in which people appear in each list which is not random.
So in order to make the lists look more random I had to make people's positions in the room random too. So the way I solved this is by adding a shuffler action which mixes the Person arrays:
public static void shuffle(Person[] arr) {
Random rgen = new Random();
for (int i = 0; i < arr.length; i++) {
int randPos = rgen.nextInt(arr.length);
Person tmp = arr[i];
arr[i] = arr[randPos];
arr[randPos] = tmp;
}
}
TL;DR the generated room lists were random - but since the order of the people that got put into the rooms wasn't random the results didn't look very random. In order to solve this I shuffled the Person arrays.
I am trying to build a 4 x 4 sudoku solver by using the genetic algorithm. I have some issues with values converging to local minima. I am using a ranked approach and removing the bottom two ranked answer possibilities and replacing them with a crossover between the two highest ranked answer possibilities. For additional help avoiding local mininma, I am also using mutation. If an answer is not determined within a specific amount of generation, my population is filled with completely new and random state values. However, my algorithm seems to get stuck in local minima. As a fitness function, I am using:
(Total Amount of Open Squares * 7 (possible violations at each square; row, column, and box)) - total Violations
population is an ArrayList of integer arrays in which each array is a possible end state for sudoku based on the input. Fitness is determined for each array in the population.
Would someone be able to assist me in determining why my algorithm converges on local minima or perhaps recommend a technique to use to avoid local minima. Any help is greatly appreciated.
Fitness Function:
public int[] fitnessFunction(ArrayList<int[]> population)
{
int emptySpaces = this.blankData.size();
int maxError = emptySpaces*7;
int[] fitness = new int[populationSize];
for(int i=0; i<population.size();i++)
{
int[] temp = population.get(i);
int value = evaluationFunc(temp);
fitness[i] = maxError - value;
System.out.println("Fitness(i)" + fitness[i]);
}
return fitness;
}
Crossover Function:
public void crossover(ArrayList<int[]> population, int indexWeakest, int indexStrong, int indexSecStrong, int indexSecWeak)
{
int[] tempWeak = new int[16];
int[] tempStrong = new int[16];
int[] tempSecStrong = new int[16];
int[] tempSecWeak = new int[16];
tempStrong = population.get(indexStrong);
tempSecStrong = population.get(indexSecStrong);
tempWeak = population.get(indexWeakest);
tempSecWeak = population.get(indexSecWeak);
population.remove(indexWeakest);
population.remove(indexSecWeak);
int crossoverSite = random.nextInt(14)+1;
for(int i=0;i<tempWeak.length;i++)
{
if(i<crossoverSite)
{
tempWeak[i] = tempStrong[i];
tempSecWeak[i] = tempSecStrong[i];
}
else
{
tempWeak[i] = tempSecStrong[i];
tempSecWeak[i] = tempStrong[i];
}
}
mutation(tempWeak);
mutation(tempSecWeak);
population.add(tempWeak);
population.add(tempSecWeak);
for(int j=0; j<tempWeak.length;j++)
{
System.out.print(tempWeak[j] + ", ");
}
for(int j=0; j<tempWeak.length;j++)
{
System.out.print(tempSecWeak[j] + ", ");
}
}
Mutation Function:
public void mutation(int[] mutate)
{
if(this.blankData.size() > 2)
{
Blank blank = this.blankData.get(0);
int x = blank.getPosition();
Blank blank2 = this.blankData.get(1);
int y = blank2.getPosition();
Blank blank3 = this.blankData.get(2);
int z = blank3.getPosition();
int rando = random.nextInt(4) + 1;
if(rando == 2)
{
int rando2 = random.nextInt(4) + 1;
mutate[x] = rando2;
}
if(rando == 3)
{
int rando2 = random.nextInt(4) + 1;
mutate[y] = rando2;
}
if(rando==4)
{
int rando3 = random.nextInt(4) + 1;
mutate[z] = rando3;
}
}
The reason you see rapid convergence is that your methodology for "mating" is not very good. You are always producing two offspring from "mating" of the top two scoring individuals. Imagine what happens when one of the new offspring is the same as your top individual (by chance, no crossover and no mutation, or at least none that have an effect on the fitness). Once this occurs, the top two individuals are identical which eliminates the effectiveness of crossover.
A more typical approach is to replace EVERY individual on every generation. There are lots of possible variations here, but you might do a random choice of two parents weighted fitness.
Regarding population size: I don't know how hard of a problem sudoku is given your genetic representation and fitness function, but I suggest that you think about millions of individuals, not dozens.
If you are working on really hard problems, genetic algorithms are much more effective when you place your population on a 2-D grid and choosing "parents" for each point in the grid from the nearby individuals. You will get local convergence, but each locality will have converged on different solutions; you get a huge amount of variation produced from the borders between the locally-converged areas of the grid.
Another technique you might think about is running to convergence from random populations many times and store the top individual from each run. After you build up a bunch of different local minima genomes, build a new random population from those top individuals.
I think the Sudoku is a permutation problem. therefore i suggest you to use random permutation numbers for initializing population and use the crossover method which Compatible to permutation problems.
Complete newbie here guys. I'm working on a Java program to prompt the user for 3 variables which are used to calculate a future investment's value. Everything works perfectly, except when it comes time to put both my datatypes into ONE array.
Here's what the output SHOULD look like:
Year Future Value
1 $1093.80
2 $1196.41
3 $1308.65
...
This is what mine looks like:
Year 1
Future Value 1093.81
Year 2
Future Value 1196.41
Year 3
Future Value 1308.65
...
My year is an int value and my Future value is a double (rounded). I've been sitting here racking my brain and all the forums I can find and haven't been successful. Every time I put both value into an array I get an error about putting two different datatypes together. Any insight would be greatly appreciated. Below is the code for my full program:
import java.util.Scanner;
class investmentValue {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter investment amount: $");
double i = s.nextDouble();
System.out.print("Enter percentage rate: ");
double r = s.nextDouble()/100;
System.out.print("Enter number of years: ");
int y = s.nextInt();
for (y=1; y<=30; y++) {
double f = futureInvestmentValue(i,r,y);
System.out.println("Year " + y);
System.out.println("Future Value " + f);
}
}
public static double futureInvestmentValue (double investmentAmount, double monthlyInterestRate, int years){
double value=1;
value = investmentAmount*Math.pow((1+(monthlyInterestRate/12)),(years * 12));
double roundValue = Math.round(value*100.0)/100.0;
return roundValue;
}
}
One solution is to start by implementing a pad function. Something like,
public static String pad(String in, int len) {
StringBuilder sb = new StringBuilder(len);
sb.append(in);
for (int i = in.length(); i < len; i++) {
sb.append(' ');
}
return sb.toString();
}
Now we can combine that with String.format() to get the dollars and cents, use a consistent printf() for the header and output lines. To get something like,
// Print the header.
System.out.printf("%s %s%n", pad("Year", 12), "Future Value");
for (int y = 1; y <= 30; y++) {
String year = pad(String.valueOf(y), 13); // <-- One more in your alignment.
String fv = String.format("$%.2f", futureInvestmentValue(i,r,y));
System.out.printf("%s %s%n", year, fv);
}
The System.out.println command isn't the only method available to you!
Try this in your loop:
System.out.print(y); // note that we use print() instead of println()
System.out.print('\t'); // tab character to format things nicely
System.out.println(f); // ok - now ready for println() so we move to the next line
Naturally, you'll want to do something similar to put your headings in.
PS - I'm pretty sure this is just an output formatting question - you don't really want to put all these values into a single array, right?
Given that you really are looking for formatted output, it may be better to use the printf() method.
The following inside the loop (instead of the 3 lines I wrote above) should do the trick (untested - I haven't used printf() format strings in a long, long time).
System.out.printf("%i\t$%0.2f", y, f);
EDIT: edited to answer your question in the comments about constructors... You should also check out this for further understanding
You could create a class that will hold both of the arrays...
This would give you a single object, let's call it StockData, that holds two arrays for the two separate types you need. You need to create the object once and then insert the data separately by type.
class StockData {
double[] data1;
int[] data2;
// default constructor
StockData() {
}
// constructor
StockData(double[] data1, int[] data2) {
this.data1 = data1;
this.data2 = data2;
}
// getters, setters...
}
Then you add data to an array of its type:
// using default constructor to add a single value to both arrays
StockData sd = new StockData();
sd.data1[INDEX_X] = YOUR_DOUBLE;
sd.data2[INDEX_X] = YOUR_INT;
// using default constructor to add all data to both arrays
StockData sd = new StockData();
sd.data1 = YOUR_ARRAY_OF_DOUBLE;
sd.data2 = YOUR_ARRAY_OF_INTS;
// using constructor to add all array data directly
StockData sd = new StockData(YOUR_ARRAY_OF_DOUBLE, YOUR_ARRAY_OF_INTS);
You could also have an object that will hold the double and int value, so the object will represent a single stock information of 2 values and then create an array containing those objects...
class StockData {
double data1;
int data2;
// default constructor same as before
// constructor
StockData(double data1, int data2) {
this.data1 = data1;
this.data2 = data2;
}
// getters, setters...
}
// ...
Adding data:
// create an array of StockData objects
StockData[] sd = new StockData[TOTAL_AMOUNT_OF_DATA];
// ... obtain your data
// using default constructor to add a single value to the array
sd[INDEX_X] = new StockData();
sd[INDEX_X].data1 = YOUR_DOUBLE;
sd[INDEX_X].data2 = YOUR_INT;
// using constructor to add all data directly
sd[INDEX_X] = new StockData(YOUR_DOUBLE, YOUR_INT);
If you want the program to have an specific format you could try to change your code and put this where your for is:
System.out.println("Year Future Value");
for (y=1; y<=30; y++) {
double f = futureInvestmentValue(i,r,y);
System.out.print(y);
System.out.println(" " + f);
}
this way you will have your output in the format you need without using arrays. But if you want to do an array for this you could declare an array of objects and create a new object with two attributes (year and future value)
Also your class name is investmentValue and it is recommended that all classes start with upper case it should be InvestmentValue
I hope that this can help you
A fun data structure you would be able to use here is a Map (more specifically in Java, a HashMap). What you are doing is associating one value with another, an integer to a double, so you could make something that looks like this:
Map<Integer, Double> myMap = new HashMap<>();
This would take the year as the integer, and the double as the price value, and you could iterate over the map to print each value.
Additionally if you really are looking for a "multidata type array," Java automatically casts from integer to double should you need to. For example:
int i = 2;
double[] arr = new double[2];
arr[0] = 3.14
arr[1] = i;
The above code is perfectly valid.
I've got an issue getting a method to read a file, then converting it to an integer. Here is a brief explanation of the program. It is essentially a car dealership inventory that keeps track of the vehicles in the lot by keeping them written down in a text file. When the program starts it will need to read the file and put all the current cars into an array so they can be displayed. Then the rest of the program will do other things like remove cars and add news ones etc. The part I am at is when the program first starts it needs to read the file, but I can't seem to get it to work.
The text file consists of 6 lines in total; 4 numbers first then 2 words respectively. I want the method to read the first four lines and convert those into integers and store them in a temporary array. Then after that it will read the next two lines and store those in a temporary array as well. Afterwards I take all these stored values and send them to a constructor. The constructor is then stored in an Arraylist and the Arraylist can be accessed anytime. In the output it does all of this just fine. But it wants to run through the method a second time despite barriers in place to prevent this.
Here is the code. Its a class and not the main program. I will try to explain the program as best I can inside the code.
public class Vehicle {
//All the different private variables for the constructors and methods
private int intholder[], year, type, kilometres, price, loop;
private String make, model, myline, holder[];
//The Arraylist that the different vehicle objects will be stored
ArrayList<Vehicle> allCars = new ArrayList<Vehicle>();
//The Default constructor
public Vehicle(){
make = "Vehicle Make";
model = "Vehicle Model";
type = 0;
year = 0;
kilometres = 0;
price = 0;
}
//The constructor that has information sent to it
public Vehicle(int _type, int _year, int _kilometres, int _price, String _make, String _model){
make = _make;
model = _model;
type = _type;
year = _year;
kilometres = _kilometres;
price = _price;
}
//Text file information
/*
* CAR TYPE CODE:
* 1 - Sedan
* 2 - Truck
* 3 - Crossover
* 4 - SUV
* 5 - Sports
*
* There is a total of 6 lines for each car and are as follows
* 1 - int Type integer
* 2 - int Year
* 3 - int Kilometres
* 4 - int Asking price
* 5 - String Make
* 6 - String Model
*/
//The method in question. It reads through the file, converts the integers and stores them,
//stores the strings, and sends all the information to the constructor
public void readCars()throws IOException{
BufferedReader readFile = new BufferedReader(new FileReader("C:/Users/David/Desktop/FinalProject/Carlot.txt"));
//Setting the length of the temporary arrays
holder = new String[2];
intholder = new int[4];
//The main loop in the method.
do{
//Read the first 4 lines of the file and convert them to integers.
//The try catch shouldn't have to be there because the first 4 lines
//of the file are all numbers, but I put it in there to see when it was messing up.
for(int i = 0; i < 4; i++){
myline = readFile.readLine();
try{
intholder[i] = Integer.parseInt(myline);
}
catch(NumberFormatException e){
System.out.println(e);
}
//Had this in here to see how many lines down the file it would go before messing up.
System.out.println(myline);
}
//Loop to store the Strings
for(int i = 0; i < 2; i++){
myline = readFile.readLine();
holder[i] = myline;
System.out.println(myline);
}
//Sends all the data to the constructor
Vehicle V = new Vehicle(intholder[0], intholder[1], intholder[2], intholder[3], holder[0], holder[1]);
//Several if statements to determine which subclass of vehicle it is.
if(intholder[0]==1){
Sedan S = new Sedan();
allCars.add(S);
}
else if(intholder[0]==2){
Truck T = new Truck();
allCars.add(T);
}
else if(intholder[0]==3){
Crossover C = new Crossover();
allCars.add(C);
}
else if(intholder[0]==4){
SUV U = new SUV();
allCars.add(U);
}
else if(intholder[0]==5){
Sports P = new Sports();
allCars.add(P);
}
//Only break the loop if the myline equals null
}while(myline != null);
//if the loop breaks, close the file
readFile.close();
}
Now I think I know where it is going wrong. At the end of the do/while, it checks if "myline" is null. And because the last time it read the file it was still a String the loop continues. The last time it goes through the loop, everything is null so trying to convert the integer is impossible so I get errors. But I have no idea how to get it to read the file at the end of the loop without going to the next line. Here is what the text file looks like.
1
2007
150250
5000
Toyota
Corolla
2
2005
240400
4500
Chevorlet
Silverado
I can't have it read at the end of the loop because if it does and there are still more cars after the one I just did, It goes into the next line when the loop restarts everything is thrown off.
Any help is appreciated, Thanks!
Use a labeled break statement in your for loops to simply exit out of the main do while loop when myline becomes null. The way other objects are being instantiated within the loop doesn't leave much room for easy refactoring hence the use of a labeled break makes sense here.
outerloop:
do {
for (int i = 0; i < 4; i++) {
if ((myline = readFile.readLine()) == null) break outerloop;
// ..
}
for (int i = 0; i < 2; i++) {
if ((myline = readFile.readLine()) == null) break outerloop;
// ..
}
// ..
} while (myline != null);
Maybe you could use a while loop instead of a do-while loop and read the next line from the file before anything else. Something like this:
String myline = null;
while( (myline = readFile.readLine()) != null ) {
// All your logic...
}
readFile.close();
The condition of while loop does the following: first, read the next line of the file with myline = readFile.readLine(). The previous statement returns the value of myline, so now we check that it is not null with the comparison:
(myline = readFile.readLine()) != null