How do I iterate over a Java array of variable length.
I guess I would setup a while loop, but how would I detect that I have reached the end of the array.
I guess I want something like this [just need to figure out how to represent myArray.notEndofArray()]
index = 0;
while(myArray.notEndofArray()){
system.out.println(myArray(index));
index++;
}
for(int i = 0; i < array.length; i++)
{
System.out.println(array[i]);
}
or
for(String value : array)
{
System.out.println(value);
}
The second version is a "for-each" loop and it works with arrays and Collections. Most loops can be done with the for-each loop because you probably don't care about the actual index. If you do care about the actual index us the first version.
Just for completeness you can do the while loop this way:
int index = 0;
while(index < myArray.length)
{
final String value;
value = myArray[index];
System.out.println(value);
index++;
}
But you should use a for loop instead of a while loop when you know the size (and even with a variable length array you know the size... it is just different each time).
Arrays have an implicit member variable holding the length:
for(int i=0; i<myArray.length; i++) {
System.out.println(myArray[i]);
}
Alternatively if using >=java5, use a for each loop:
for(Object o : myArray) {
System.out.println(o);
}
You've specifically mentioned a "variable-length array" in your question, so neither of the existing two answers (as I write this) are quite right.
Java doesn't have any concept of a "variable-length array", but it does have Collections, which serve in this capacity. Any collection (technically any "Iterable", a supertype of Collections) can be looped over as simply as this:
Collection<Thing> things = ...;
for (Thing t : things) {
System.out.println(t);
}
EDIT: it's possible I misunderstood what he meant by 'variable-length'. He might have just meant it's a fixed length but not every instance is the same fixed length. In which case the existing answers would be fine. I'm not sure what was meant.
here is an example, where the length of the array is changed during execution of the loop
import java.util.ArrayList;
public class VariableArrayLengthLoop {
public static void main(String[] args) {
//create new ArrayList
ArrayList<String> aListFruits = new ArrayList<String>();
//add objects to ArrayList
aListFruits.add("Apple");
aListFruits.add("Banana");
aListFruits.add("Orange");
aListFruits.add("Strawberry");
//iterate ArrayList using for loop
for(int i = 0; i < aListFruits.size(); i++){
System.out.println( aListFruits.get(i) + " i = "+i );
if ( i == 2 ) {
aListFruits.add("Pineapple");
System.out.println( "added now a Fruit to the List ");
}
}
}
}
Related
Im trying to figure out a way to override a specific array in this scenario.
Im iterating through a LinkedList and when I encounter the Element null I am supposed to add the index of the Element to an already defined array of ints.
public int [] indexes()
{
int [] result = new int [0];
int counter = 0;
Element current = first;
int k = 0;
for(int i = 0 ; i< size() ; i++)
{
if(current.getContent()==null)
{
counter++;
}
}
int [] temp = new int [counter];
current = first;
for(int i = 0 ; i< size() ; i++)
{
if(current.getContent()==null)
{
temp[k++] = i ;
}
}
result = temp;
return result;
As you can already see, I have an array with no elements in it and a length of 0.
Afterwards Im iterating through the List to check if and how many Elements are null. When I find one I increment the counter.
I set up a new temporary array with the length of the counter and the fill the temporary Element with the indexes.
1st Question : Does the line result = temp; work as intended? Does the array called result now contain the array of temp?
2nd Question : How can I check if an Element is null in a LinkedList without getting a NullpointerException? I tried using the following in my if conditions:
current == null
current.getContent() == null
current.equals(null)
current.getContent().equals(null)
All of those returned a counter of 0 which means it didnt increment the counter when encountering a Null-Element. How can I rewrite the if conditions?
Question 1: Yes. result and temp refer to the same data.
Question 2: your for loop is problematic:
for(int i = 0 ; i< size() ; i++)
{
if(current.getContent()==null)
{
temp[k++] = i ;
}
}
You're not changing current, so it's always pointed to the first element.
I'm not sure if you're using Java's LinkedList<> or implementing your own.
I wrote this little program. I think it demonstrates what you're trying to do:
import java.util.*;
public class Foo {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();;
list.add("Hello");
list.add("There");
list.add(null);
for (String str: list) {
System.out.println(str != null ? str : "<null>");
}
ArrayList<Integer> indexes = new ArrayList<Integer>();
int index = 0;
for (String str: list) {
if (str == null) {
indexes.add(index);
}
++index;
}
for (Integer thisIndex: indexes) {
System.out.println(thisIndex);
}
}
}
At the end, you would need to convert from ArrayList into an int[]. But the output from this little guy is:
$ javac Foo.java && java Foo
Hello
There
<null>
2
I was able to override the result array with this line.
result = temp;
Also the way to check if an Element is null in the List was:
current.getContent() == null;
And last I actually forgot setting the current pointer to the next Element which actually was my biggest problem:
current = current.getSucc();
Thanks for everyone's help and time. I really appreciate it!
Whenever I try to run the code I get IndexOutOfBoundsException. I have tried numerous of ways fixing it but none of them have helped. The method should add a new String element "****" into ArrayList before every String which's length is equal to 4. In this case, it must add "****" before "5555".
Where could be the problem?
import java.util.ArrayList;
public class Main {
public static ArrayList<String> markLength4(ArrayList<String> list) {
int sum = 0;
for ( int i = 0; i < list.size(); i++) {
if (list.get(i).length() == 4) {
list.add(list.indexOf(i), "****");
}
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("ddddddddddddd");
list.add("fffffffffffff");
list.add("5555fdgdfg");
list.add("5555");
list.add("5555");
System.out.println(markLength4(list));
}
}
list.indexOf(i) will return -1, since i doesn't appear in your list. Therefore adding an element at the -1 position will throw an exception.
If you change list.add(list.indexOf(i), "****") to list.add(i, "****");, you'll get an infinite loop that will end with OutOfMemoryError, since the newly added String also has a length() of 4, so another String will be added on the next iteration, and so on.
i is not in your arraylist - it is a list of String, not Integer. That means that list.indexOf(i) == -1.
From your description, I think you mean:
list.add(i, "****");
but you will also need to increment i, e.g.
list.add(i++, "****");
to avoid the infinite loop that Eran mentions.
Or, of course, you can iterate the list backwards, and avoid the infinite loop/need to change the loop variable inside the loop body:
for ( int i = list.size() - 1; i >= 0; i--)
{
if (list.get(i).length() == 4)
{
list.add(i, "****");
}
}
import java.util.ArrayList;
public class Test {
public static ArrayList<String> markLength4(ArrayList<String> list) {
int sum = 0;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).length() == 4) {
list.add(i++, "****");
}
}
return list;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("ddddddddddddd");
list.add("fffffffffffff");
list.add("5555fdgdfg");
list.add("5555");
list.add("5555");
list = markLength4(list);
for (String x : list) {
System.out.println(x);
}
}
}
You'll loop forever this way, because there's 4-lengthened strings forward and you keep adding...
You can solve this by looping from the end, but you'll have to be careful with your index(you should add and increment the index to avoid that)
After Editing list.add(i++,"****"); the code should work just fine.
Notable
If you want to add before use i++;.
If you want to add after your match use ++i;.
list.indexOf(i) is not present in the list . It will produce -1
-1 is not available in ArrayList
Replace the Line
list.add(list.indexOf(i), "****");
with the following line
list.set(i, "****");
It replace the existing content of the List with new element in the index of i with new element i.e (****)
list.indexOf(i) where i is an int and therefore not in your list will throw your error as stated in comments (index -1).
use either of the following:
list.add("str") to add a String to the end of the list
OR
list.set(i, "****") which will set the value at a given index to this new string.
In the markLength4 method, by adding the element in the for loop you keep adding Strings and increasing the list size. You need a flag that tells the index and then ends the loop. You can try something like that
public static ArrayList<String> markLength4(ArrayList<String> list) {
int i = 0;
boolean found = false;
int pos = 0;
while(i < list.size() && !found){
if (list.get(i).length() == 4) {
found = true;
pos = i;
}
i++;
}
list.add(pos, "****");
return list;
}
I'm trying to create a program that takes user input and sorts it alphabetically as it comes in using compareTo String operations (not array.sort) and prints the final sorted array at the end. I've got most of the body of this problem down but am lost once I get to the sort function. Does anyone have any ideas on how I might be able to finish out the SortInsert method?
import java.util.*;
public class SortAsInserted {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int array_size = GetArraySize();
String[] myArray = new String[array_size];
for (int i = 0; i < array_size; i++){
String nextString = GetNextString();
String[] sortedArray = SortInsert(nextString, myArray);
}
PrintArray(sortedArray);
}
input.close();
}
}
public static String[] SortInsert(String nextString, String[] myArray){
for(int i = 0; i < myArray.length;)
if (nextString.compareToIgnoreCase(myArray[i]) > 0) {
i++;
//if current text is less(alphabetically) than position in Array
}else if (nextString.compareToIgnoreCase(myArray[i]) < 0){
}
}
public static int GetArraySize(){
Scanner input = new Scanner(System.in);
System.out.print("How many items are you entering?: ");
int items_in_array = input.nextInt();
return items_in_array;
}
public static void PrintArray(String[] x) {
for (int i = 0; i < x.length; i++){
System.out.print(x[i]);
}
}
public static String GetNextString(){
Scanner input = new Scanner(System.in);
System.out.println("Enter the next string: ");
String next_string = input.nextLine();
return next_string;
}
}
There are a number of problems with this code. First I'll answer your immediate question, then enumerate some of the other problems.
The SortInsert method takes a String[] that will have been initialized with null values, so you will need to take that into account. The for loop would look something like this. (I'm using comments instead of writing the actual code since I'm not doing the project)
for (int i=0; i<myArray.length; ++i) {
if (myArray[i] == null) {
// we found a blank spot. use it to hold nextString.
break;
} else if (nexString.compareToIgnoreCase(myArray[i]) < 0) {
// nextString should be in spot i, so make room for it
// by shuffling along whatever is in the array at "i" and later
// by one place, then put nextString into position "i"
break;
}
// otherwise we'll just move to the next position to check
}
Now for the other issues.
You have a Scanner object in main that is never used. There's no point in having it and closing it at the end if your other methods make their own.
myArray will always be the sorted array so there's no point in making a local variable called sortedArray and return it from SortInsert. Note that your attempt to print sortedArray would fail anyway because that local variable is only in scope within the for loop.
When printing it should be myArray being passed to PrintArray.
If you're going to sort as you go, the TreeMap data structure is what you should be using, not an array. However, if you want to sort as you go with an array, you need to add some lines into your else if clause in SortInsert (should be sortInsert, BTW). (Another question: why is it else if rather than just else?)
The lines should create a new array of size one greater than the existing array, copy the first i-1 elements of the old array to the new array, put the new element in position i, then copy the remaining elements of the old array into positions one greater in the new array.
Once you find the position you wish to insert at, you have to shift all of the following elements down by one. Something like the following:
String temp = array[position];
for (int j = position+1; j < array_size-1; j++) {
String temp2 = array[j];
array[j] = temp;
temp = temp2;
}
array[array_size-1] = temp;
Here is my code to distinguish the differences between two txt files. The only problem is i get an out of bounds exception if i dont subtract 1 from the arrayList, so right now it is not running for all of the elements, how do i fix this?
import java.io.*;
import java.util.*;
public class myfilereader
{
public static void main (String[] args) throws java.io.IOException
{
int temp = 0;
ArrayList<String> ArrayList1 = new ArrayList<String>();
ArrayList<String> ArrayList2 = new ArrayList<String>();
ArrayList<String> ArrayList3 = new ArrayList<String>();
try
{
Scanner File1 = new Scanner(new File("/Users/Home/Desktop/File1.txt"));
while (File1.hasNext())
{
ArrayList1.add(File1.next());
}
Scanner File2 = new Scanner(new File("/Users/Home/Desktop/File2.txt"));
while (File2.hasNextLine())
{
ArrayList2.add(File2.next());
}
}
catch (FileNotFoundException ex)
{
ex.printStackTrace();
}
for (String ArrayList : ArrayList1)
{
System.out.println("File 1: " + ArrayList1);
}
for (String ArrayList : ArrayList2)
{
System.out.println("File 2: " + ArrayList2);
}
if(ArrayList1.size()>ArrayList2.size())
{
for(int i=0; i<ArrayList1.size()-1; i++)
{
if(ArrayList1.get(i).equals(ArrayList2.get(i)))
{
temp++;
}
}
}
if(ArrayList2.size()>ArrayList1.size())
{
for(int i=0; i<ArrayList2.size()-1; i++)
{
if(ArrayList2.get(i).equals(ArrayList1.get(i)))
{
temp++;
}
}
}
if(temp == 0)
System.out.println("The files are the same.");
else
System.out.println("There are " + temp + " differences between the files");
}
}
This is the problem:
if(ArrayList1.size()>ArrayList2.size())
{
//ArrayList1 is bigger!!!!
for(int i=0; i<ArrayList1.size()-1; i++)
{
if(ArrayList1.get(i).equals(ArrayList2.get(i)))
// ArrayList2 does not contain as many elements as ArrayList1
{
temp++;
}
}
}
therefore. You can have your loop from 0 -> ArrayList.size() but be sure to use the shorter list as the limit for the loop! :-)
Alternatively, you can replace:
for(int i=0; i<ArrayList1.size()-1; i++)
With:
for (String s : ArrayList1)
This is called a for-each loop and can be used for more readable simpler iteration.
As Sara Seppola already mentioned, you need to use the smallest of the two sizes to compare the elements in the two lists. Currently, you're using the biggest of the two, which guarantees that you'll go out of bounds on the smaller list.
Also, you should be using ArrayList1.size() and not ArrayList1.size()-1 in your loop limits, as the strictly less than check in your loop condition currently causes i to iterate from 0 to ArrayList1.size()-2 - which is one too short. Again, the index-out-of-bounds is not caused by the -1, but rather because of the incorrect size used in the condition.
Finally, you're not accounting for the case where the lists have equal sizes. Currently, your code gives "The files are the same" since there's not if-test which passes when ArrayList1.size() == ArrayList2.size().
if(ArrayList1.size() >= ArrayList2.size())
{
// Here, ArrayList1.size() >= ArrayList2.size()
// Use the smallest size as limit so we stay in bounds for both
// In this case, that's ArrayList2.size()
// When the lists have equal length, both sizes could be used
// as limit so it doesn't really matter whether you use
// > or >= in the test of the above if-statement
for(int i=0; i<ArrayList2.size(); i++)
{
if(ArrayList1.get(i).equals(ArrayList2.get(i)))
{
temp++;
}
}
}
else
{
// Here, ArrayList1.size() < ArrayList2.size()
// so use ArrayList1.size() as the limit
for(int i=0; i<ArrayList2.size(); i++)
{
if(ArrayList2.get(i).equals(ArrayList1.get(i)))
{
temp++;
}
}
}
There's still an error in your code though: you're only comparing corresponding elements. What about the extra elements from the larger list? Those should be counted as differences as well.
A quick fix would be to simply subtract the two sizes to get the number of extra elements in the bigger list, and use that as initial value for the number of difference:
if(ArrayList1.size() >= ArrayList2.size())
{
temp = ArrayList1.size() - ArrayList2.size();
// [for loop]
}
else
{
temp = ArrayList2.size() - ArrayList1.size();
// [for loop]
}
Of course, you could still simplify your code. You could use Math.min(ArrayList1.size(), ArrayList2.size()) to get the smallest of the two sizes and remove the duplicated loop. You could also use Math.abs(ArrayList1.size() - ArrayList2.size()) to get the number of extra elements, regardless whether ArrayList1 or ArrayList2 is the largest. I'll leave that as an exercise for the reader. ;-)
if(ArrayList1.size()>ArrayList2.size())
{
for(int i=0; i<ArrayList1.size()-1; i++)
{
if(ArrayList1.get(i).equals(ArrayList2.get(i)))
{
temp++;
}
}
}
Here you first check if ArrayList1 has more items than ArrayList2, and then you loop over the bigger ArrayList1, using get(i) on ArrayList1 as well as ArrayList2.
Because ArrayList1 has more items than ArrayList2, eventually you will get an item from at index X from ArrayList1 that you cannot get from ArrayList2 because ArrayList2 contains less items.
Example: ArrayList1 has 10 items and ArrayList2 has 9 items. You enter the if because 10 > 9. Then at the last iteration in the for loop you do ArrayList1.get(9) which is fine because it has 10 items and this gets the 10th, but ArrayList2.get(9) will fail because it has only 9 items. 8 is the highest index you can work with.
The second if has the same problem, but the other way around.
A fix to stop the error from occurring would be to
for(int i = 0; i < ArrayList2.size(); i++)
{
...
This might not do what you want your code to do, but the error will be gone.
I am trying to do this problem but can't get around with it. Please tell me what i did wrong and any tips on how to solving it? Thanks.
here is the problem:
Write a method stutter that takes an ArrayList of Strings and an integer k as parameters and that replaces every string with k copies of that string. For example, if the list stores the values ["how", "are", "you?"] before the method is called and k is 4, it should store the values ["how", "how", "how", "how", "are", "are", "are", "are", "you?", "you?", "you?", "you?"] after the method finishes executing. If k is 0 or negative, the list should be empty after the call.
my code:
public static void stutter(ArrayList<String> list,int k) {
String s = "";
for(int i = 0; i<list.size(); i++) {
s = list.get(i);
}
for(int j = 0; j < k; j++) {
list.add(j,s);
}
}
Well...two things are wrong here:
You're not returning anything, which is a bit of a problem if you want to get back the modified list without changing/destroying your original data.
Your loops aren't doing anything meaningful. The first loop is only going to give you the last element in your list, and then you only add that k times. Most definitely not what you want.
I won't give the entire thing away, as this is an exercise for you, but here's some suggestions:
Create your own ArrayList<String> to return instead of that String variable. You'll also be declaring the method to return ArrayList<String>. May as well initialize it, too.
Read each word in the list passed in. Add that to the local list k times (hint: nested loops). If there's no words to be read, then the loop to add the elements isn't fired.
Here is the code
public static List<String> stutter(ArrayList<String> list,int k) {
List<String> resultList=new ArrayList<String>(); // creating new list
if(k<=0) {
return resultList; //return empty list. Return null if necessary
} else {
for(String s : list) { //looping the list input
for(int i=0;i<k;i++) {
resultList.add(s); // adding the same string k times
}
}
return resultList;
}
}
Second for loop should be nested in first for loop
And strings should be added to a newlist instead of adding them to
the samelist
Done modifications to your code.
public static void stutter(List<String> list,int k) {
String s = "";
List<String> newList=new ArrayList<String>();
if(k>0) {
for(int i = 0; i<list.size(); i++) {
s = list.get(i);
for(int j = 0; j < k; j++) {
newList.add(s);
}
}
}
list=newList; // Assigning it your input list since you want to change the actual list
System.out.println(list.toString()); //Since not returning anything, printing the data
}