Android 2.3.3
This is my code...
String[] expression = {""}; //globally declared as empty
somewhere in the code below, I am trying to assign a string to it.
expression[0] = "Hi";
I keep getting the following error...
12-08 22:12:19.063: E/AndroidRuntime(405): java.lang.ArrayIndexOutOfBoundsException
Can someone help me with this..
Can we access the index 0, directly as i am doing?
Actual Code :::
static int x = 0; // global declaration
String[] assembledArray = {""}; // global declaration
assembleArray(strSubString, expression.charAt(i)); //Passing string to the method
//Method Implementation
private void assembleArray(String strSubString, char charAt) {
// TODO Auto-generated method stub
assembledArray[x] = strSubString;
assembledArray[x+1] = String.valueOf(charAt);
x = x+2;
}
The problem is not in assembledArray[x]; it's in assembledArray[x+1].
At the first iteration, x+1 = 1, so you cannot access that part of the array. I would suggest using a dynamic array, aka an ArrayList:
ArrayList<String> assembledArray = new ArrayList<String>(); // global declaration
assembleArray(strSubString, expression.charAt(i)); //Passing string to the method
//Method Implementation
private void assembleArray(String strSubString, char charAt) {
assembledArray.add(strSubString);
assembledArray.add(String.valueOf(charAt));
}
This way, Java takes care of the resizing, and you don't need to keep track of x.
Related
I'm adding three different objects to an ArrayList, but the list contains three copies of the last object I added.
For example:
for (Foo f : list) {
System.out.println(f.getValue());
}
Expected:
0
1
2
Actual:
2
2
2
What mistake have I made?
Note: this is designed to be a canonical Q&A for the numerous similar issues that arise on this site.
This problem has two typical causes:
Static fields used by the objects you stored in the list
Accidentally adding the same object to the list
Static Fields
If the objects in your list store data in static fields, each object in your list will appear to be the same because they hold the same values. Consider the class below:
public class Foo {
private static int value;
// ^^^^^^------------ - Here's the problem!
public Foo(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
In that example, there is only one int value which is shared between all instances of Foo because it is declared static. (See "Understanding Class Members" tutorial.)
If you add multiple Foo objects to a list using the code below, each instance will return 3 from a call to getValue():
for (int i = 0; i < 4; i++) {
list.add(new Foo(i));
}
The solution is simple - don't use the static keywords for fields in your class unless you actually want the values shared between every instance of that class.
Adding the Same Object
If you add a temporary variable to a list, you must create a new instance of the object you are adding, each time you loop. Consider the following erroneous code snippet:
List<Foo> list = new ArrayList<Foo>();
Foo tmp = new Foo();
for (int i = 0; i < 3; i++) {
tmp.setValue(i);
list.add(tmp);
}
Here, the tmp object was constructed outside the loop. As a result, the same object instance is being added to the list three times. The instance will hold the value 2, because that was the value passed during the last call to setValue().
To fix this, just move the object construction inside the loop:
List<Foo> list = new ArrayList<Foo>();
for (int i = 0; i < 3; i++) {
Foo tmp = new Foo(); // <-- fresh instance!
tmp.setValue(i);
list.add(tmp);
}
Your problem is with the type static which requires a new initialization every time a loop is iterated. If you are in a loop it is better to keep the concrete initialization inside the loop.
List<Object> objects = new ArrayList<>();
for (int i = 0; i < length_you_want; i++) {
SomeStaticClass myStaticObject = new SomeStaticClass();
myStaticObject.tag = i;
// Do stuff with myStaticObject
objects.add(myStaticClass);
}
Instead of:
List<Object> objects = new ArrayList<>();
SomeStaticClass myStaticObject = new SomeStaticClass();
for (int i = 0; i < length; i++) {
myStaticObject.tag = i;
// Do stuff with myStaticObject
objects.add(myStaticClass);
// This will duplicate the last item "length" times
}
Here tag is a variable in SomeStaticClass to check the validity of the above snippet; you can have some other implementation based on your use case.
Had the same trouble with the calendar instance.
Wrong code:
Calendar myCalendar = Calendar.getInstance();
for (int days = 0; days < daysPerWeek; days++) {
myCalendar.add(Calendar.DAY_OF_YEAR, 1);
// In the next line lies the error
Calendar newCal = myCalendar;
calendarList.add(newCal);
}
You have to create a NEW object of the calendar, which can be done with calendar.clone();
Calendar myCalendar = Calendar.getInstance();
for (int days = 0; days < daysPerWeek; days++) {
myCalendar.add(Calendar.DAY_OF_YEAR, 1);
// RIGHT WAY
Calendar newCal = (Calendar) myCalendar.clone();
calendarList.add(newCal);
}
Every time you add an object to an ArrayList, make sure you add a new object and not already used object. What is happening is that when you add the same 1 copy of object, that same object is added to different positions in an ArrayList. And when you make change to one, because the same copy is added over and over again, all the copies get affected.
For example,
Say you have an ArrayList like this:
ArrayList<Card> list = new ArrayList<Card>();
Card c = new Card();
Now if you add this Card c to list, it will be added no problem. It will be saved at location 0. But, when you save the same Card c in the list, it will be saved at location 1. So remember that you added same 1 object to two different locations in a list. Now if you make a change that Card object c, the objects in a list at location 0 and 1 will also reflect that change, because they are the same object.
One solution would be to make a constructor in Card class, that accepts another Card object. Then in that constructor, you can set the properties like this:
public Card(Card c){
this.property1 = c.getProperty1();
this.property2 = c.getProperty2();
... //add all the properties that you have in this class Card this way
}
And lets say you have the same 1 copy of Card, so at the time of adding a new object, you can do this:
list.add(new Card(nameOfTheCardObjectThatYouWantADifferentCopyOf));
It can also consequence of using the same reference instead of using a new one.
List<Foo> list = new ArrayList<Foo>();
setdata();
......
public void setdata(int i) {
Foo temp = new Foo();
tmp.setValue(i);
list.add(tmp);
}
Instead of:
List<Foo> list = new ArrayList<Foo>();
Foo temp = new Foo();
setdata();
......
public void setdata(int i) {
tmp.setValue(i);
list.add(tmp);
}
I need to edit the string value in variable.
So,
00343755932
should be converted to:
0,0,3,4,3,7,5,5,9,3,2
because I must define each number as an variable array for readable one by one.
if I'm right you are trying to create an array from string. Use following code
String val = "00343755932";
int[] numberArray = new int[val.length()];
Matcher match = Pattern.compile("[0-9]").matcher(val);
int i = 0;
while(match.find()) {
System.out.println(match.group());
numberArray[i] = Integer.parseInt(match.group());
i++;
}
when I am carrying out a search operation after fetching the contacts,it shows this exception when I type the letters very fast in the search bar and the application crashes.Could you please help me out to resolve this issue.I am including the portion of the code also along
#Override
public boolean onQueryTextChange(String newtext) {
String searchString = newtext;
int textLength = searchString.length();
ArrayList<Masterlistmodel> type_name_filter = new ArrayList<Masterlistmodel>();
/* String text = edtField.getText().toString(); */
for (int i = 0; i <masterarr.size(); i++) {
String Name = masterarr.get(i).getName();
if (searchString.equalsIgnoreCase(Name.substring(0,
textLength))) {
type_name_filter.add(masterarr.get(i));
}
}
type_name_copy = type_name_filter;
listUpdate(type_name_copy);
return true;
}
#Override
public boolean onQueryTextSubmit(String arg0) {
// TODO Auto-generated method stub
return false;
}
First thing I'd point out is that we don't know what kind of object is masterarr, So I'll guess is like an ArrayList.
I'd try not to use the .size() but the .length() method, size is related to capacity and length is related to the amount of items actually in the array.
Also, as #rsinha said, I think a possible mistake is when you try to execute the equalsIgnoreCase method and the Name variable in that iteration has a lenght shorter than the lenght of the String typed by the user, so I would try:
for (int i = 0; i <masterarr.size(); i++) {
String Name = masterarr.get(i).getName();
if (searchString.equalsIgnoreCase(Name.substring(0,
Math.min(textLength,Name.length())))) {
type_name_filter.add(masterarr.get(i));
}
}
Try first using .length() and if does not work, try the changes in the for loop. I see no more in your code I could help with.
You get IndexOutOfBoundsException when you want to access an array index which is out of range. For example:
String[] myArray = new String[10];
myArray[10] = "test"; // 10 is out of limits(0-9)
Would produce such an exception.
with this:
ArrayList<String> result= new ArrayList<String>();
Then you can add elements to this list with the following:
// result[i] = trax.substring(s1+4,s2);
result.add(trax.substring(s1+4,s2));
It will work for you and it will remove this exception.
'textLength' is length of the search string entered by user. An entry of this length may not be in your master list 'masterarr'. You may try:
String Name = masterarr.get(i).getName();
if (Name.startsWith(searchString)) {
type_name_filter.add(masterarr.get(i));
}
Add the first statement in the method "onQueryTextChange"
if(newtext==null) return true;
Then try
This question already has answers here:
How to get a resource id with a known resource name?
(10 answers)
Closed 8 years ago.
Is there a way to change a reference to an ID in the Android manifest using a variable?
As in:
for(int counter6=1;counter6 <= 12; counter6++)
value = bundle.getString("value"+counter6);
TextView text1 = (TextView) findViewById(R.id.textView+counter6);
text1.setText(value);
Is it possible to have the counter6 variable used in the ID directory, so the for loop can loops through all the different text view making each one text1 respectively then setting their text to the string value?
Its not really a problem if it cant work this way it just means more lines of code to write.
You can't really make a loop on the id and increment it as it is generated but you can make an array of references and by getting that array find each TextView and update the text:
<array name="array_text_views">
<item>#id/text_view_1</item>
<item>#id/text_view_2</item>
<item>#id/text_view_3</item>
<array>
In your code, something like that:
ArrayList<TextView> myTextViews = new ArrayList<TextView>();
TypedArray ar = context.getResources().obtainTypedArray(R.array.array_text_views);
int len = ar.length();
for (int i = 0; i < len; i++){
myTextViews.add(findById(ar[i]));
}
ar.recycle();
I would usually just put a small int[] array of Ids into the code somewhere. If you have a lot of them, consider creating them programmatically (layout.addView(new TextView(..).
For example if you want to start an Activity and tell it what strings to display via the Extras Bundle you can put them directly as an array.
void startOther(String[] texts) {
Intent i = new Intent( /* ... */);
i.putExtra("texts", texts);
// start via intent
}
Now inside that Activity I would put the ids as a "constant".
// hardcoded array of R.ids
private static final int[] TEXT_IDS = {
R.id.text1,
R.id.text2,
// ...
};
And then use both the Bundle and the id Array for example like this:
// a List of TextViews used within this Activity instance
private List<TextView> mTextViews = new ArrayList<TextView>(TEXT_IDS.length);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.something);
// find all TextViews & add them to the List
for (int id : TEXT_IDS) {
mTextViews.add((TextView)findViewById(id));
}
// set their values based on Bundle
String[] stringArray = savedInstanceState.getStringArray("texts");
for (int i = 0; i < mTextViews.size() && i < stringArray.length; i++) {
mTextViews.get(i).setText(stringArray[i]);
}
}
I have a table in Parse which is named Customer_Information. And there is a column named username. I want to retrieve all the values in the username column and store it to array. After storing, i want to set it to a single textview. Is this possible? I've tried this code but it has an error ArrayIndexOutOfBounds.
public class Users extends Activity{
private static final String tbname = "Customer_Information";
private static final String uname = "username";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.users);
TextView text = (TextView)findViewById(R.id.text);
ParseQuery query = new ParseQuery(tbname);{
try{
List<ParseObject> test = query.find();
for(int x=0;x<test.size();x++){
String[] str = {test.get(x).getString(uname)};
text.setText("Username: "+str[x]+"\n");
}
}
catch (com.parse.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
The problem is most likely with this line:
text.setText("Username: "+str[x]+"\n");
You are trying to access an index, but you are accessing it with x. If all the ParseObjects return an array of the same length, after a while, as x increases, it will become greater than that array's greatest index, resulting in an IndexOutOfBoundsException.
I suggest you first do some testing: print out the values of str, figure out what index you need, then change the line so it uses the constant index. Based on the fact that you only have 1 element in the array since you do
String[] str = {test.get(x).getString(uname)};//one element array
the index is most likely 0:
text.setText("Username: "+str[0]+"\n");
If you are not going to make str any larger than 1 element, discard it and use just a single String.