Filling a List<List<String>> with values - java

So I've been running into a few errors. When I try to add an event to a date in a month, I try to add an event into the date ArrayList but the list doesn't have that number available. So I want to know how to instantiate a list that will have the amount of days in it.
I know you can instantiate how many months there are by using
public static List<List<String>> events = new ArrayList<List<String>>(12);
which 12 being the number of months, but is there a way to make all 12 of the arrays have 31 slots open for days?

I'd recommend completely changing your design.
Use a map of date against event list - to deal with multiple events on same date
Lazy initialize map. Create a method that returns list for given day/month, if it isn't there, add it.
Code
private class Events {
Map<Date, List<String>> events = new HashMap<Date, List<String>>();
public List<String> getEvents(int month, int day) {
Calendar calendar = GregorianCalendar.getInstance();
calendar.set(0, month, date, 0, 0, 0);
Date date = calendar.getTime();
List<String> list = events.get(date);
if (list == null) {
list = new ArrayList<String>();
events.put(date, list);
}
return list;
}
}
Usage
Events events = new Events();
events.getEvents(11, 25).add("Christmas");
events.getEvents(0, 1).add("New years day");

I think you should change your design plan. Make a class Month with an ArrayLisy<String>(31) which you create 12 times in another class called year or something. For myself I would do this and it makes your code more readable!
Also, when it is a fixed number of slots (and you don't want it to go over that limit), use basic arrays

Why not use
List<Map<String, Integer>> = new List<HashMap<String, Integer>>();

While #Adam's answer is probably the best way to handle this particular problem, the general question of how to initialize a multidimensional list structure should also be addressed.
The standard idiom for constructing and initializing a multi-dimensional data structure like the one you describe is to use a set of for loops, like this:
int[][] myArray = new int[][myFirstDimension];
for(int i=0; i<a.length; i++){
int [] a = new int[mySecondDimension];
for(int j=0; j<b.length; j++){
a[j] = myInitialValue;
}
myArray[i] = a;
}
Nested ArrayLists are constructed in a similar way to arrays, but with one important difference: The parameter passed to the ArrayList is only an initial capacity, not the initial size. In fact, ArrayList actually makes no guarantees about how much space it allocates, although in practice, IIRC, it typically allocates the next power of two. Attempting to index into the ArrayList before you have initialized its contents will throw an IndexOutOfBoundsException.
Thus, when initializing nested ArrayLists, we typically do it like this:
List<List<String>> myList = new ArrayList<>();
for(int i=0; i<myFirstDimension; i++){
List<String> a = new ArrayList<>();
for(int i=0; i<mySecondDimension; i++){
a.add(""); // or `null`, if that is needed
}
myList.add(a);
}

Related

wanted put array list items into variables using loop

i am dynamically adding items to array-list after i wanted to
Initialize Variables using this array-list items
my array-list is
ArrayList<String> dayCountList = new ArrayList<String>();
i try to do like this but it doesn't work
for (int i = 0; i < dayCountList.size() ;i++) {
double day+"i" = Double.parseDouble(dayCountList.get(i));
}
You can create a array or array list of double type like this.
ArrayList<String> dayCountList = new ArrayList<String>();
.
.
double day[]=new double[dayCountList.size()];
// now use your loop like this
for (int i = 0; i < dayCountList.size() ; i++) {
day[i] = Double.parseDouble(dayCountList.get(i));
}
Now you can call your variables like day[0], for first element
day[1] ,for second and so on.
Hope this helped you.
If you are doing this, then you probably did not understand the purpose of array lists is. One purpose of array list is exactly to avoid creating a whole bunch of variables named day1, day2, day3 and so on.
You seem like you want to transform every element in the array list to a doubles. Why not create another ArrayList<Double> or double[] to store the transformed elements? Instead of writing day1, day2, you can say days.get(0), days.get(1) in the case of array lists. With arrays, you can do days[0], days[1] and so on.
ArrayList<Double> days = dayCountList.stream()
.mapToDouble(Double::parseDouble)
.boxed()
.collect(Collectors.toList());
// or
double[] days = dayCountList.stream()
.mapToDouble(Double::parseDouble).toArray()

Looking for a workaround for dynamic variable declaration in a for loop

I have a number of repetitions of a task I would like to put in a for loop. I have to store a time series object as an IExchangeItem, a special class in openDA (a data assimilation software).
This is one of the tasks (that works):
HashMap<String, TimeSeries> items = new LinkedHashMap<String, TimeSeries>();
...
TimeSeries tsc1Q = new TimeSeries(time,value);
id = "Q1";
tsc1Q.setId(id);
this.items.put(id,tsc1Q);
IExchangeItem c1Q = new TimeSeries(tsc1Q);
What changes across the tasks is the id of the time series object and the name of IExchangeItem. I have to create a new IExchangeItem object for each time series.
This is what I tried in the for loop:
HashMap<String, TimeSeries> items = new LinkedHashMap<String, TimeSeries>();
...
TimeSeries temp;
for (int i = 0; i<readDataDim[0]; i++) {
value[0] = values[i];
id = exchangeItemIDs[i];
temp = new TimeSeries(time,value);
temp.setId(id);
this.items.put(id,temp);
IExchangeItem <??> = new TimeSeries(temp); //* How can I handle this line?
}
I know I cannot use dynamic variable names in java and that arrays, lists, or maps are commonly used to work around this issue (this is why I used <??> in the code snippet above. However, I'm a relative beginner with java and I have no clue how I can work around this specific problem since I have to have a new invocation of IExchangeItem for each time series.
From here I take it that my IExchangeItem created in the for loop will not be accessible outside the for loop so how can I initialise n replicates of IExchangeItem outside the for loop?
Edit:
Does a HashMap create n instances of IExchangeItem if I try something like this?
HashMap<String,IExchangeItem> list = new LinkedHashMap<String,IExchangeItem>();
Just one suggestion, try to write a separate method when you can pass the size of the array or a fixed number (based on array), then you created a hashMap and add that many number of instances with its keys, and values, cannot post this as a comment and hence posting it as an answer.
Try to create a new method using the value of readDataDim[0] value,
public Map<String, IExchangeItem> createAndInitialzeMap(int maxValue) {
Map<String, IExchangeItem> map = new HashMap<>();
String temp = "tempName";
for(int i =0; i < maxValue ; i ++ ) {
map.put(temp+i, new IExchangeItem());
}
return map;
}
return this way you can initialize your map along with its variable name and you can use it in your app anywhere. However I would consider refactoring if such code exists and time permits.
One more thing you should read about hashMap. :) :)

How to sort multiple ArrayLists based off order of another?

I'm having trouble figuring out the best way to go out about sorting multiple lists based off of the sorted order of one list. Currently the lists are in order based off their indices. The departureTime list holds strings of time in the format (00:00 AM/PM). They are initialized like this:
public static List<String> departureTime = new ArrayList<String>();
public static List<String> mode = new ArrayList<String>();
public static List<String> busNo = new ArrayList<String>();
public static List<String> busStopName = new ArrayList<String>();
public static List<String> arrivalTime = new ArrayList<String>();
public static List<String> dur = new ArrayList<String>();
I need to sort all lists based of the sorted order of departure times in the departureTime ArrayList. What's the best way to go about sorting these lists without changing the resulting data structure. Any assistance would be highly appreciated.
Thanks,
Matt
As stated in the comment, it would have been easier to create an object containing all the values, and then just sort the object list.
If this is for some reason impossible, you will need to code your own sort method, for instance selection sort, while making the permutations operations on all objects in the lists.
Here is a simple but non optimal algorithm. Feel free to adapt it for some other sort. This would work only if all lists have the same length.
public void sort() {
String[] departureTimeArray = departureTime.toArray(new String[departureTime.size()]);
String[] modeArray = mode.toArray(new String[mode.size()]);
//here you convert the other lists to arrays
int lenD = departureTimeArray.length;
int j = 0;
for(int i=0;i<lenD;i++){
j = i;
for(int k = i;k<lenD;k++){
if(departureTimeArray[j].compareTo(departureTimeArray[k])>0){
j = k;
}
}
permutation(departureTimeArray, i, j);
permutation(modeArray, i, j);
//here do the same for other arrays
}
departureTime = Arrays.asList(departureTimeArray);
mode = Arrays.asList(modeArray);
//here convert back arrays to list
}
private void permutation(String[] array, int i, int j) {
String tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
See for instance here for the selection sort algorithm :
selection sort
You could save the index of each departure time before sorting in a Hashmap<String, Integer>. Then sort only that list as usual, then save again the indexes in another hashmap.
Now you know that a given string was in position n before sorting and is now in position n' after sorting. So you can manually swap the other lists's elements with this info.
This approach is brittle, because if there were repeated elements in the list, then you can't know which one was which after sorting. So you are better off creating a container class as suggested in the other answers.

Remove a specific string from an array of string

I have an array like this:
String n[] = {"google","microsoft","apple"};
What I want to do is to remove "apple".
My problem is very basic,however,I searched the website and I found out that java doesn't really support the deleting feature from an array.I also heard to use Java Utils, because it's so simple to remove an item....I tried to find Java Utils on google, but almost all links are dead.
So finally...is there any way to remove a string from an array of string?
Even if I use an ArrayList I can't find a method to generate a random item in it! For ex: in a normal array I generate a string like this:
String r = myAL[rgenerator.nextInt(myAL.length)];
In an arraylist it doesn't work....maybe you know a solution...
Define "remove".
Arrays are fixed length and can not be resized once created. You can set an element to null to remove an object reference;
for (int i = 0; i < myStringArray.length(); i++)
{
if (myStringArray[i].equals(stringToRemove))
{
myStringArray[i] = null;
break;
}
}
or
myStringArray[indexOfStringToRemove] = null;
If you want a dynamically sized array where the object is actually removed and the list (array) size is adjusted accordingly, use an ArrayList<String>
myArrayList.remove(stringToRemove);
or
myArrayList.remove(indexOfStringToRemove);
Edit in response to OP's edit to his question and comment below
String r = myArrayList.get(rgenerator.nextInt(myArrayList.size()));
It is not possible in on step or you need to keep the reference to the array.
If you can change the reference this can help:
String[] n = new String[]{"google","microsoft","apple"};
final List<String> list = new ArrayList<String>();
Collections.addAll(list, n);
list.remove("apple");
n = list.toArray(new String[list.size()]);
I not recommend the following but if you worry about performance:
String[] n = new String[]{"google","microsoft","apple"};
final String[] n2 = new String[2];
System.arraycopy(n, 0, n2, 0, n2.length);
for (int i = 0, j = 0; i < n.length; i++)
{
if (!n[i].equals("apple"))
{
n2[j] = n[i];
j++;
}
}
I not recommend it because the code is a lot more difficult to read and maintain.
Arrays in Java aren't dynamic, like collection classes. If you want a true collection that supports dynamic addition and deletion, use ArrayList<>. If you still want to live with vanilla arrays, find the index of string, construct a new array with size one less than the original, and use System.arraycopy() to copy the elements before and after. Or write a copy loop with skip by hand, on small arrays the difference will be negligible.
You can't remove anything from an array - they're always fixed length. Once you've created an array of length 3, that array will always have length 3.
You'd be better off with a List<String>, e.g. an ArrayList<String>:
List<String> list = new ArrayList<String>();
list.add("google");
list.add("microsoft");
list.add("apple");
System.out.println(list.size()); // 3
list.remove("apple");
System.out.println(list.size()); // 2
Collections like this are generally much more flexible than working with arrays directly.
EDIT: For removal:
void removeRandomElement(List<?> list, Random random)
{
int index = random.nextInt(list.size());
list.remove(index);
}
import java.util.*;
class Array {
public static void main(String args[]) {
ArrayList al = new ArrayList();
al.add("google");
al.add("microsoft");
al.add("apple");
System.out.println(al);
//i only remove the apple//
al.remove(2);
System.out.println(al);
}
}

Java: Sorting multiple ArrayLists synchronously or a single mapped ArrayList

I've only started learning Java about 3 months ago and this is my first post here, so please bear with me.
I have multiple ArrayLists built from parsed XML that are directly related to each other in order. The arrays are later put into a single mapped ArrayList (groupData) to be read with a SimpleAdapter which creates the list in the Android GUI.
What I want to do is sort the list in alphabetical order based on one array (arr_title) and the other arrays stay in synchronized order to it. It doesn't matter where the sorting happens as long as the final displayed list is sorted. I expect it would be best to sort the mapped array once it's built. The simpler or easier to understand the code the better, but don't want the sorting to go very slow either. I have about 140 objects per array, but that could expand considering the XML is pulled from the web.
I've spent hours searching Google and tried a number of things with little progress. Collections.sort(arr_title) will sort the one array as I want it, but then the other arrays don't match up and doing the same thing to the other arrays obviously just sorts them individually as I don't want. I've noticed mention of using the TreeMap type and Comparator for similar sorting, but couldn't figure out how to use them in this case probably because the examples didn't provide a big enough picture for me to understand.
The sample below is where most of the stuff happens after the separate arrays are created.
List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
Map<String, String> group;
int item = 0;
do {
group = new HashMap<String, String>();
group.put("title", arr_title.get(item));
group.put("desc", arr_desc.get(item));
group.put("num", Integer.toString(arr_num.get(item)));
groupData.add(group);
item++;
} while (item < arr_num.size());
SimpleAdapter adapter = new SimpleAdapter(this, groupData, android.R.layout.simple_list_item_2, new String[] {"title", "desc", "num"}, new int[]{android.R.id.text1, android.R.id.text2});
setListAdapter(adapter);
I tend to agree, using a comparator would be easier.
i.e.
Comparator<HashMap<String, String>> comparator = new Comparator<HashMap<String, String>>() {
#Override
public int compare(HashMap<String, String> object1, HashMap<String, String> object2)
{
return object1.get("title").compareToIgnoreCase(object2.get("title"));
}
};
Collections.sort(groupData, comparator);
'title' being the key in the hash to sort on.
Welcome to SO.
First of all, there are Java conventions to name the variables. Have a look at the Naming conventions
Secondly, Java is an Object Oriented Language, so you have to change your mind a little bit about how you approach problems.
In this particular case, you want all the data scattered among 3 arrays to be together. Well, create a class for it.
public class Data implements Comparable{
private String title;
private String desc;
private int num;
public Data(String title, String desc, int num){
//set the private fields here
}
//You may want to write some setters and getters here for individual fields.
public int compareTo(Object o){
//here you compare an item with other item. Remember to cast the object o to Data.
// Read http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Comparable.html to know what to return
}
}
And then in your main class:
int item = 0;
do {
Data group = new Data(arr_title.get(item),arr_desc.get(item),arr_num.get(item);
groupData.add(group);
item++;
} while (item < arr_num.size());
Collections.sort(groupData);
Last but not least, there are better ways to iterate through a set in Java. Read about Iterators. It's a much secure and cleaner way to go through an array or a set.
It sounds to me like you've make a classic beginner mistake (for which you can be forgiven): not thinking enough in terms of objects.
Java's an object-oriented language. It sounds to me like your multiple lists of related items should really be a single List of objects that each contain their set of the items you're currently putting into multiple lists. Then you can sort that List of Objects using a Comparator any way you wish. All the related attributes are nicely encapsulated inside their object, where they belong. They stay together no matter how you sort them.
Objects are all about encapsulation and information hiding.
I finally figured it out! Thanks to a bigger project coming across a similar issue essentially forcing me to get this solved. Everything outside this sample is mostly the same as it was at the original post apart from some changed variable names. I'm not sure if this is the best way to do it, but it gets the job done at a very acceptable speed and I can actually understand how it works.
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
// Put separated item details in a HashMap for each item,
// then insert it in sorted order to list.
for(int n = 0; n < arrayTitle.size(); n++) {
HashMap<String, String> item = new HashMap<String, String>();
item.put("title", arrayTitle.get(n));
item.put("desc", arrayDesc.get(n));
try {
int c, i = 0;
do {
// Compare new title with titles existing in list
// from beginning to end or until title is found that it goes before.
c = arrayTitle.get(n).compareTo(list.get(i).get("title"));
i++;
} while (c > 0 & i < list.size());
i--;
if(c > 0) {
// New item goes after all others currently in list.
list.add(item);
} else if (c < 0) {
// New item goes before an item already in list.
list.add(i, item);
}
} catch (Exception e) {
// If nothing in list to compare with, add first item.
list.add(item);
}
}
SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, new String[] {"title", "desc"}, new int[]{android.R.id.text1, android.R.id.text2});
setListAdapter(adapter);

Categories