Reading a file into a list? - java

this problem cannot be solved this time, due to major errors in the code which need to be corrected first before submitting the question.

Instead of:
if (result = true)
do
if (result)
Also, instead of:
for (int index = 0; index < lineList.size() - 1; index =+2)
do
for (int index = 0; index < lineList.size(); index +=2)
Edited: Two issues on your for statement:
index < lineList.size() - 1 will not hit the last item. Either remove - 1 or change < for <=
Index does not increment its value. Change index =+2 for index +=2.

One obvious bug I could find was:
if (result = true)
which should be:
if (result == true)

You have a section with two errors. Compare with my sample:
for (int index = 0; index < lineList.size() - 1; index += 2)
if (usr.add(list.get(index))) System.out.println(list.get(index));
Or, in another idiom:
boolean take = true;
for (String line : lineList) {
if (take) usr.add(line);
take = !take;
}

One problem is here:
if (result = true)
You probably meant to write:
if (result == true)
A better way to write this check is:
if (result)
There might also be an off-by-one bug in index < lineList.size() - 1. If the file contains an odd number of lines, your current code will disregard the last line. I say might since it's not entirely clear what you expect to happen in this case.
Finally, the whole thing can be implemented with a single loop and without the list (i.e. just with the set).

Related

looping through List and removing element skipps certain elements

If have a workflow that removes elements of a List by a certain criteria. However certain items are skipped? Why is this happening?
List<Integer> listWithAge = new ArrayList<>();
int randomNumber = 100;
for (int i = 0; i < randomNumber; i++) {
listWithAge.add(i);
}
// this is my loop
for (int i = 0; i < listWithAge.size(); i++) {
System.out.println(i);
if ((listWithAge.get(i) % 3) == 2) listWithAge.remove(i);
}
Above code is my loop. I replaced my condition with something simpler. If I run this code my second loop only runs for 67 turns instead of 100.
It is problematic to iterate over a list and remove elements while iterating over it.
If you think about how the computer has to reconcile it, it makes sense...
Here's a thought experiment for you to go through.
If you have a list that is size 10 and you want to remove elements 1, 5, and 9 then you would think maybe the following would work:
List<String> listOfThings = ...some list with 10 things in it...;
list.remove(0);
list.remove(4);
list.remove(8);
However, after the first remove command, the list is only size 9.. Then after the second command, it's size has become 8. At this point, it hardly even makes sense to do list.remove(8) anymore because you're looking at an 8-element list and the largest index is 7.
You can also see now that the 2nd command didn't even remove the element now that you wanted.
If you want to keep this style of "remove as I go" syntax, the more appropriate way is to use Iterators. Here's an SO that talks about it and shows you the syntax you would need (see the question). It's easy to read up on elsewhere too.
How Iterator's remove method actually remove an object
Skipping a value would be the result of your list getting out of sync with your loop index because the list is reduced in size. This causes you to hop over some locations since the reduction in size affects future locations that have not been reached.
So the first thing you could do is simply correct the synchronization by decrementing i when you remove a value from the list. This will keep index at the same spot as the list shifts "left" caused by the removal.
for (int i = 0; i < listWithAge.size(); i++) {
if ((listWithAge.get(i) % 3) == 2) listWithAge.remove(i--);
}
The other option is to loop thru the list backwards.
for (int i = listWithAge.size()-1; i >= 0; i--) {
if ((listWithAge.get(i) % 3) == 2) {
listWithAge.remove(i);
}
}
This way, no values should be skipped since the removing of the element does affect the loop index's future positions relative to the changing size of the list.
But the best way would be to use an iterator as has already been mentioned by
Atmas
As a side note, I recommend you always use blocks {} even for single statements as I did above in the if block. It will save you some serious debugging time in the future when you decide you need to add additional statements and then wonder why things are no longer working.
And deleting like this from a list is very expensive, especially for large lists. I would suggest that if you don't have duplicate values, you use a Set. Otherwise, instead of deleting matching values, add the non-matching to a second list.
List<Integer> listWithAge = new ArrayList<>();
int randomNumber = 100;
for (int i = 0; i < randomNumber; i++) {
listWithAge.add(i);
}
// this is my loop
List<Integer> itemsToBeDeleted = new ArrayList<>();
for (int i = 0; i < listWithAge.size(); i++) {
System.out.println(i);
if ((listWithAge.get(i) % 3) == 2) {
itemsToBeDeleted.add(i);
}
//delete all outside the loop
//deleting inside the loop messes the indexing of the array
listWithAge.removeAll(itemsToBeDeleted);

Displaying a string in an int array (for validation check)

I'm using a for loop as a form of validation check to make sure the input for the variable stScore is a number over 0 and under or equal to 100, example shown here, if the input isn't correct, the score parameter will be shown as 0:
for(int i = 0; i < 3; i++)
if ((stScore[i] > 0 && stScore[i] <= 100))
score[i] = stScore[i];
else
score[i] = 0;
My question is if there is any way to display a string (to say something like error!) in place of that 0 instead? Of course at the base of things you can't have an int array include a string, but I was wondering if there is a workaround for this.
Thanks
A workaround would be to ascribe some magic meaning to a particular int value that would never otherwise occur in your data. E.g., declare a constant:
private static final int INVALID_SCORE = -1;
Use it both when assigning:
if ((stScore[i] > 0 && stScore[i] <= 100))
score[i] = stScore[i];
else
score[i] = INVALID_SCORE;
And when printing:
System.out.println(score[i] != INVALID_SCORE ? score[i] : "Invalid score!");
The disadvantage is that it will cause problems if you forget to treat the value specially in later code that uses the data.
No, unfortunately you cannot :(. But we usually don't use 0 as an error code. In these situations I use Integer.MIN_VALUE to indicate an error.
So your code will be like this:
for(int i = 0; i < 3; i++)
if ((stScore[i] > 0 && stScore[i] <= 100))
score[i] = stScore[i];
else
score[i] = Integer.MIN_VALUE;
I suggest you not to use 0. Because 0, when it is an exit code, it usually means "OK". In C++, the main method returns 0 when the program exits with no errors. Alternatively, Integer.MAX_VALUE can be used as well.
For more readable code, you can declare a constant called ERROR:
final int ERROR = Integer.MIN_VALUE;
The best option would be to set any invalid inputs to -1. Then on output you could have an if statement the checks for the error value (-1) and outputs an appropriate error message.
It's bad practice to mix types in any sort of collection; avoid it whenever possible.
throw new IllegalArgumentException("your score is below zero");
That would seem to be appropriate

ArrayList Retrieve First and Last Result without Sorting ArrayList

I have an ArrayList of String, and I would like to retrieve the first and last result of the names after calculating the order of alphabets. Below is my code snippet:
ArrayList<String> list = new ArrayList<String>(20);
list.add("Charles Darwin");
list.add("Albert Einstein");
list.add("Issac Newton");
list.add("Tony Hoare");
list.add("Grace Hopper");
list.add("Edgar Dijkstra");
list.add("Ada Lovelace");
list.add("Charles Babbage");
list.add("Stephen Hawking");
String biggest = "";
String smallest = "";
for (int i = 0; i < list.size(); i++) {
String first = list.get(i);
for (int j = 0; j < list.size(); j++) {
String second = list.get(j);
if (!first.equalsIgnoreCase(second)) {
if (first.compareToIgnoreCase(second)>0){
biggest=first;
}
if (first.compareToIgnoreCase(second)<0){
smallest=first;
}
}
}
}
System.out.println(biggest);
System.out.println(smallest);
I am able to retrieve every value for comparison, however, the results are always showing Stephen Hawking as the biggest and smallest.
My desired results are Ada Lovelace as biggest and Tony Hoare as smallest.
You can use Collections.min / max
Your conditional statements seem to wrong.
if (first.compareToIgnoreCase(second)>0){
biggest=first;
}
if (first.compareToIgnoreCase(second)<0){
smallest=first;
}
You're comparing the element in the outer loop to the element in the inner loop. You never make a comparison against the biggest and smallest.
This should help you find the biggest and smallest String in your list.
String biggest = list.get(0);
String smallest = list.get(0);
for (int i = 1; i < list.size(); i++) {
if(list.get(i).compareToIgnoreCase(biggest) > 0)
biggest = list.get(i);
if(list.get(i).compareToIgnoreCase(smallest) < 0)
smallest = list.get(i);
}
Alternatively, you can use Collections.min() and max() as stated in one of the other answers.
are your required to use List ? You might want to see http://docs.oracle.com/javase/7/docs/api/java/util/SortedSet.html. then you can use first() and last() method
I'm new to Java, but I can still recognize multiple issues with this code:
Why are you hard coding initial capacity to 20?
Why are you using indexed loops instead of for each?
Why are you using a nested loop to find min/max?
Use else instead of running the same comparison twice
If first always equals second biggest and smallest will remain uninitiated
And last, and directly dressing your question, all your code does is finding if the last item is greater & smaller than any of the other items in the list, not all of them, since you keep ignoring previous findings and not using biggest/smallest as a condition in any of your comparisons.

Index out of bounds exception in homework

I'm trying to do a homework assignment. I have to use dynamic programming to display whether the next person to move is in a win/loss state. I don't need help with the actual problem, I need help with an index out of bounds exception I'm getting that baffles me. I'm only going to paste part of my code here, because I only need the for loops looked at. I also don't want anyone in my class seeing all my code and copying it. If you need more data please let me know. So here is the code:
if(primeArray[x] == true){
for(int i = 1; i <= x; i++){
if(primeArray[i]== true){
newRowNumber = x - i;
}
if(dynaProgram[newRowNumber][columnNumber] < minimum){
minimum = dynaProgram[newRowNumber][columnNumber];
}
}
}
//COMPOSITE CASE FOR X!
else{
for(int k = 1; k <= x; k++){
if((primeArray[k] == false)){
newRowNumber = x - k;
}
if(dynaProgram[newRowNumber][columnNumber] < minimum){
minimum = dynaProgram[newRowNumber][columnNumber];
}
}
For some reason the if(primeArray[i] == true runs correctly, but I'm getting index out of bounds exception on if(primeArray[k] == false. The only difference between these two is the use of the variable k over i in the for loop.(the for loops are identical) I haven't used either variables anywhere else in my code. I have no idea why this occurs for one but not the other. In both cases, x remains the same number.
I am also getting an index out of bounds exception on the second minimum = dynaProgram[newRowNumber][columnNumber], while the first doesn't encounter an error. I know it's probably a stupid error, but I can't figure it out. If I change the 'k' for loop to k < x the index of out bounds exception in the if(primeArray[k] == false line goes away, but then it isn't correct. (The error on the second minimum = dynaProgram[newRowNumber][columnNumber] doesn't go away however.)
All this code is in a nested for loop which iterates through the rows and columns in the table to fill them in. If I remove the above code and just put dynaProgram[rowNumber][columnNumber] = 1 I don't have an issue, so I don't believe that is the problem.
When accessing an array of length 5 (for example)
int[] fred = new int[5];
the first element will be fred[0] and the last will be fred[4]
So when doing something like:
if(primeArray[i]== true){
Make sure that i is less than the array length. Using a value of i equal to the array length will throw an exception.

Checking if ArrayList element exists or not

I'll try to explain this as best I can. I have an ArrayList of String's. I am trying to implement server-side paging for a webapp. I am restricted to the number of items per page (6 in this case) which are read from this ArrayList. The ArrayList is, lets say, the entire catalog, and each page will take a section of it to populate the page. I can get this working just fine when there are enough elements to fill the particular page, its when we hit the end of the ArrayList where there will be less than 6 items remaining for that pages segment. How can I check if the ArrayList is on its last element, or if the next one doesn't exist? I have the following code (in pseudo-ish code):
int enterArrayListAtElement = (numberOfItemsPerPage * (requestedPageNumber - 1));
for (int i = 0; i < numberOfItemsPerPage; i++) {
if (!completeCatalog.get(enterArrayListAtElement + i).isEmpty() {
completeCatalog.get(enterArrayListAtElement + i);
}
}
The if in the code is the problem. Any suggestions will be greatly appreciated.
Thanks.
It sounds like you want:
if (enterArrayListAtElement + i < completeCatalog.size())
That will stop you from trying to fetch values beyond the end of the list.
If that's the case, you may want to change the bounds of the for loop to something like:
int actualCount = Math.min(numberOfItemsPerPage,
completeCatalog.size() - enterArrayListAtElement);
for (int i = 0; i < actualCount; i++) {
// Stuff
}
(You may find this somewhat easier to format if you use shorter names, e.g. firstIndex instead of enterArrayListAtElement and pageSize instead of numberOfItemsPerPage.)
Can't you just get
completeCatalog.size()
and compare it to i? i.e to answer the question "is there an ith element" you say
if (i<completeCatalog.size())
You just need to add a second expression to look whether the end of the list was reached already:
int enterArrayListAtElement = (numberOfItemsPerPage * (requestedPageNumber - 1));
for (int i = 0; i < numberOfItemsPerPage; i++) {
if (enterArrayListAtElement + i < completeCatalog.size() && !completeCatalog.get(enterArrayListAtElement + i).isEmpty() {
completeCatalog.get(enterArrayListAtElement + i);
}
}
An ArrayList has the method of size(), which returns the number of elements within the List.
Therefore, you can use this within the if statement to check you've not went too far.
For example,
if(enterArrayListAtElement + i < completeCatalog.size()) {
...
}

Categories