I'm working on a project for work involving a JTable with a dynamic number of columns. Each column is basically a separate transaction but I do not know the number of transactions a file will have ahead of time.
Typically when I create a JTable I know how many columns I will have and I declare it like this:
String header[] = new String[]{
"Tag","Transaction1"
};
For this project however there can be any number of transactions each time the program is used so I would need to dynamically add columns based upon the length of a certain array before I even create my rows. (The first row is actually going to also be used as a header).
So I have an array with a given length, but I don't know how to use this value in a loop, at least not with creating an object like the code above shows.
For example let's say the user uploads a file that has 3 transactions.. I would need my String header[] to read:
String header[] = new String[]{
"Tag","Transaction1","Transaction2","Transaction3"
};
I'd considered possibly creating an array list and adding the transactions to this using a counter and a loop, then possibly extracting the values into the String[] header although I'm not sure if this is the best approach and even still how exactly to make it work.
I actually found the answer to this.. Apparently I need to scrap the entire array and add them like this..
DefaultTableModel tableModel = new DefaultTableModel();
for(String columnName : columnNames){
tableModel.addColumn(columnName);
}
jTable.setModel(tableModel);
A good option for you would be to have an ArrayList to dynamically add or remove elements from the List.
Then, when necessary, you can turn that ArrayList into an array of Strings, like..
ArrayList<String> elements = new ArrayList<String>();
elements.add("Transaction 1");
elements.add("Transaction 2");
elements.add("Transaction 3");
Object[] elementArray = elements.toArray();
I thing you dont need to use an Array, use better an List, this because you can increase the size as much as you need, iterate it, parse it to string-Arrays etc.
Example
List<String> transactions = new ArrayList<String>();
transactions.add("Tag");
// later
transactions.add("Transaction1");
transactions.add("Transaction2");
// print it
for (final String string : transactions) {
System.out.println(string);
}
List<String> headerList = new ArrayList<>();
headerList.add("Tag");
for(int i=1; i <= transactions.length; i++){
headerList.add("Transaction" + i);
}
String[] header = headerList.toArray(new String[headerList.size()]);
I believe what you're looking for is an ArrayList, not an Array nor List, as this allows for dynamic allocation.
The syntax would be:
List<String> header = new ArrayList<String>();
header.add("Tag");
That initializes it. Then, use length() from your File class to set a parameter for a loop, then dynamically add the result of string concatenation with the "Transaction" + your loop index to your ArrayList.
That'd look like:
for (int i = 1; i <= file.length(); i++){
header.Add("Transaction" + i);
}
And, then you can convert it back to an array of strings with:
String[] headerArray = header.toArray(new String[header.size()]);
Related
I have a method that takes vararg Array of strings
void count(long delta, String... tags);
I have a predefined array of tags for the most cases
String[] tags = { "foo_tag:Foo",
"bar_tag:Bar",
"baz_tag:Baz"
};
and only one tag to be added to predefined tags in each call "project_id:12345"
So the call of count should look like this:
count(delta, "foo_tag:Foo", "bar_tag:Bar", "baz_tag:Baz", "project_id:12345");
How can I simply create a new array containing my existing one plus additional element just in place of calling the method?
Something like this hypothetical Arrays.append method:
count(delta, Arrays.append(tags, "project_id:12345"));
This is storing statistics operation, not a business logic, so I want this operation to be as fast as possible.
Currently, I have helper method appendTag, but it doesn't look elegant as for me
private String[] appendTag(String[] tags, String s)
{
String[] result = new String[tags.length + 1];
System.arraycopy(tags, 0, result, 0, tags.length);
result[result.length-1] = s;
return result;
}
In java, arrays have a fixed size so it won't be possible to extend an array by appending new elements to it.
You will need to create a new array with a larger size and copy the first one elements into it, then add new elements to it, but it's not dynamic yet.
What I can suggest is to use a Collection maybe an ArrayList you will profit from its built-in methods like .add()
There is no easy way to expand an array by one element and add something new. But if you were working with a list instead, you could easily add a new element and then convert it to an array when calling the method:
String[] tags = { "foo_tag:Foo",
"bar_tag:Bar",
"baz_tag:Baz"
};
List<String> tagList = new ArrayList<String>(Arrays.asList(tags));
tagList.add("project_id:12345");
count(delta, tagList.toArray(new String[0]));
If you think you will have a long term need for this, then perhaps consider changing the implementation of count() to use a list instead of an array. You could also overload this method and expose a version which accepts list instead of array.
I have elements that is declared in a list variable such as:
List<List<String>> textList = new ArrayList<>();
The elements are added such as:
textList.add(Arrays.asList(p)); //adding elements
The only way I could output the elements inside the variable is by using:
for(List<String> s: textList){
System.out.println(s); }
which output elements like this:
[He is a boy.]
[He likes apple.]
[She is a girl.]
Now, I would like to store them in an array so that the elements will look like this when outputted.
[He is a boy., He likes apple., She is a girl.]
I've tried
String[] textArr = new String[textList.size()];
textArr = textList.toArray(textArr);
for(String s : textArr){
System.out.println(s);}
but I got an error about:
Exception in thread "main" java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at java.util.Arrays.copyOf(Arrays.java:3213)
at java.util.ArrayList.toArray(ArrayList.java:407)
So, how do I convert the elements inside a list into array using the proper way. Thanks!
Your problem is that you are not storing Strings in your list textList.
textList.add(Arrays.asList(p));
As the type says, you have a List of List of String here.
So you can't take the elements of that list and assume they are Strings. Because they aren't! The error message tells you that: toArray() wants strings it can put into that array of strings, but you give it a List of List of String!
But thing is: what you are describing here doesn't make sense in the first place. Printing strings shouldn't care if strings are in an array or a List.
What I mean is: when you manually iterate a List or an array to print its content, then it absolutely doesn't matter if you iterate a List or an array. The code is even the same:
for (String someString : someCollection) {
System.out.println(someString);
}
someCollection can be both: array or List!
In other words: the idea to turn data that is nicely stored within Lists into arrays for printing simply doesn't make any sense. To the contrary: you are probably calling toString() on your List object, and the result of that ... isn't 100% what you want. But I guarantee you: calling toString() on some array will result in something you totally will not want.
Long story short: forget about converting to Arrays; simply iterate your List of List of Strings and use a StringBuilder to collect the content of that collection the way you want to see it (you simply append those [ ] chars to that builder in those places you want them to see).
(if you insist on that conversion to array, the key point there to understand is that only a List of String can be turned into an array of string. So a List of List ... doesnt work that easy).
Using streams and flatMap, you can do this:
List<List<String>> list = ...;
String[] strings = list.stream().flatMap(l -> l.stream()).collect(Collectors.toList()).toArray(new String[0]);
This is equivalent to using a loop (You can use two nested for loops as suggested in the comments instead by replacing the addAll, but why?):
List<List<String>> list = ...;
List<String> stringList = new ArrayList<>();
for (List<String> l : list)
stringList.addAll(l);
String[] strings = list.toArray(new String[stringList.size()]);
You can use Iterator in order to go over every element of the list, instance of the for each statement (I personally like the iterators more). The code you could use would be something like
//Your list
List<List<String>> textList = new ArrayList<>();
//The iterators
Iterator<List<String>> itList = textList.iterator();
Iterator<String> itString;
//The string to store the phrases
String s[] = new String[textList.size()];
int i =0;
//First loop, this seeks on every list of lists
while(itList.hasNext()){
//Getting the iterator of strings
itString = itList.next().iterator();
s[i] = "";
//2nd loop, it seeks on every List of string
while(itString.hasNext()){
s[i] = s[i].concat(itString.next());
}
s[i] = s[i].concat(".");
i++;
}
I just started using the enhance for-loop. I want to know if I can use this loop to copy an array. I want to iterate through every element of a certain array and copy it to a new one. It would also be nice to use the enhanced for-loop to instantiate my new array (instead of a typical for-loop). In my current implementation I do know how big I want the array to be, but for future reference I would like to know if I can do this, and if so, how.
My specific plans for what I'm doing might help to answer my question. What I am doing is retrieving a line of text from a text file then calling split( "," ) on that string - this returns an array of Strings. I want to store this array in memory so I can play with it later.
The way I understand the enhanced for-loop to work is that the first value is assigned the current position in the array and the second value is the array that is to be traversed.
I was wondering if there are other formats for for-loops, besides: for ( initialization; termination; iterate ) and for ( Object o : list[] ).
If you want to keep to the enhanced for loop for copying an array, there is one mayor problem: the enhanced for loop doesn't have a counter. Inserting elements into an array however requires a counter. So you could of course do this manually like so:
String[] array = {"A", "Bb", "c", "dD"};
String[] newArray = new String[array.length];
int i=0;
for(String stuff : array) {
newArray[i++] = stuff;
}
This is entirely possible but not really the idea behind the enhanced for loop.
More in line with the intention would be something like this:
String[] array = {"A", "Bb", "c", "dD"};
List<String> list = new ArrayList<String>();
for(String stuff : array) {
list.add(stuff);
}
String[] newArray = new String[list.size()];
list.toArray(newArray);
That way not only do you follow the idea behind the enhanced for loop, you also allow for the possibility that array.length() != newArray.length() (because, say, you filtered the array).
EDIT: as of Java 7, there are indeed only the two for loops you mentioned. This may change in future versions though if it seems sensible; after all, the enhanced for loop was only added in Java 5 (as can be seen here).
To my knowledge, there are only standard for(init; termination; iterataion) loops and for-each for(type o : iterable) loops.
First, knowing the size ahead of time shouldn't be a concern. For instantiating the new array use the original array's .length field: new String[original.length]; as shown below.
Moving along, for what you are doing, the standard for loop is appropriate for two reasons:
You would need to nest two for-each loops in order to iterate both
loops, making it more hassle than a standard for loop. (or add an externally defined counter, as in blalasaadri's solution)
More importantly, in the case of a primitive data type or a String, the variable declared before the : in the for-each loop represents the value of each successive element, and is not a reference to the actual element. As such, any changes to the variable are gone once the loop iterates. I'm not sure if this holds for 'normal' objects (ie: not String), as I've not tried, though I want to find out now.
To illustrate:
String[] sArr = {"foobar"};
for(String s : sArr){
s = "openbar";
}
is the equivalent of:
String[] sArr = {"foobar"};
String s = sArr[0];
s = "openbar";
Sadly, for sArr[0], there is no open bar, same old foobar.
As for solutions, if you can import java.util.Arrays; then try:
String[] copyStrings = Arrays.copyOf(arrStrings, arrStrings.length);
Or, if you need to roll your own:
public String[] copyArray(String[] original){
String[] dupe = new String[original.length]; //I assume you want equal length
for(int i = 0; i < original.length; i++){
dupe[i] = original[i]; //single iterator traverses both arrays
}
return dupe;
}
// copy contents of Object[] arr1 into Object[] arr2
arr2 = new int[arr1.length];
int i=0;
for(Object c:arr1){ //store an element of arr1 in c iteratively
arr2[i] = c;
i++;
}
I apologize in advance if this question is stupid but I'm working on something at the moment which required me to implement a loop to parse through a List of objects of type MenuItem. Inside the loop I need to store the name of the object in a String variable.
However I am unsure about how many items will be in the List and therefor do not know how many variables I require. Can I somehow declare variables on the fly inside of the loop???
Below is my current code:
for(int i = 0; i != orderItems.size(); i++){
MenuItem item = orderItems.get(i);
String itemName = item.getName();
}
The reason for the loop above is because when it exits I want to send all of the itemName variables to a db via a Http post request. So I can pass as a parameter like this:
new RequestTask().execute(url, itemName1, itemName2, itemName3);
Any help would be much appreciated!
You can use varargs to specify a method that accepts a list of variables. In the end it is just a method that accepts an array of such variables. So you will end with
new RequestTask().execute(url, items); // items is String[]
If you do not know a priori the number of Strings, store them in a List. You then can get the number of items in the list, create an array big enough and fill it. Or, use the method toArray that will do just that.
Here is the ArrayList syntax I use all the time when looping on an unknown value. I then convert it to a normal array for further processing.
List<String> itemNameList = new ArrayList<String>();
for(int i = 0; i != orderItems.size(); i++) {
MenuItem item = orderItems.get(i);
itemNameList.add(item.getName());
}
String[] itemNameArray = new String[itemNameList.size()];
itemNameList.toArray(itemNameArray);
Put them into a list of some sort ie;
ArrayList<String> itemNameList = new ArrayList<String>();
for(int i = 0; i != orderItems.size(); i++){
MenuItem item = orderItems.get(i);
String itemName = item.getName();
itemNameList.add(itemName);
}
How can I convert this type of Arraylist to Two Dimensional Arraylist ?
ArrayList<ArrayList<String>> two = new ArrayList<ArrayList<String>>();
In android ExpandableListView does not allow to use Arraylist to populate the listview. But I have to dynamically populate the data from JSON web service. How Can I solve this issue ?
Any help would be great !
If you're coming from a JSON object, then the data is already in the format that you want. It's already an array of arrays. You can just loop through the first array assigning the second as you go.
String[][] foo = new String [myJsonObject.getStringArray("arrayOfArrays")).length() ][];
for(int i = 0; myJsonObject.exists("array_" + i); i++){
foo[i] = myJsonObject.getStringArray("array_" + i);
}
I didn't test this, so the syntax might not be 100% but you get the idea.
You just create a Hashmap first and put data to the hashmap. And then Create a Arraylist and put hashmap inside arraylist. That is i done in my case of multidimensional array.