How to insert array of objects in Firestore? - java

I want to insert an array of objects in Firestore? I'm able to add from Firestore console, but doing it from Java it's not working? Here I'm attaching my console snapshot and code is:
val map = HashMap<String, Any>()
map["one"] = request.records
dayFormDoc.set(map)
Here request.records is an array.

try this,
Android
Map<String, Object> docData = new HashMap<>();
docData.put("listExample", Arrays.asList(1, 2, 3));
java
ArrayList<Object> arrayExample = new ArrayList<>();
Collections.addAll(arrayExample, 5L, true, "hello");
docData.put("arrayExample", arrayExample);
more information https://firebase.google.com/docs/firestore/manage-data/add-data
Hope it's help full.

You cannot simply add an array to a Cloud Firestore database because you'll get an error that looks like this:
Caused by: java.lang.IllegalArgumentException: Invalid data. Arrays are not supported; use a List instead (found in field array)
So to solve this problem, you should convert your array to a list as in the following lines of code.
For Android:
Map<String, Object> map = new HashMap<>();
String[] array = {"One", "Two", "Three"};
map.put("array", Arrays.asList(array));
dayFormDoc.update(map);
For Kotlin:
val map = HashMap<String, Any>()
val array = arrayOf("One", "Two", "Three")
map["array"] = Arrays.asList(*array)
dayFormDoc.update(map)

Related

Convert from map to arraylist

I tried to convert a Map<String,ArrayList<Object>> to ArrayList<Object> using this code:
Collection<ArrayList<Object>> coll = map().values();
List list = new ArrayList(coll);
ArrayList<Object> arrayList = new ArrayList<>(list.size());
arrayList.addAll(list);
However, the arraylist I got still groups objects by key still as collection.
How can I convert to ArrayList of separate Objects?
You can use Java 8 Streams:
List<Object> list = map.values().stream()
.flatMap(ArrayList::stream)
.collect(Collectors.toList());
Without Streams, you'll have to iterate over the elements of your first List and call arrayList.addAll() for each of them separately.
A non stream version would be:
List<Object> accumulator = new ArrayList<>();
for(ArrayList<Object> a : map.values())
accumulator.addAll(a);
same result can be achieved by using following traditional approach as well -
Map<String, ArrayList<Object>> map = new HashMap<>();
ArrayList<Object> objects1 = new ArrayList<>();
objects1.add("data1");
objects1.add("data2");
objects1.add("data3");
map.put("key1", objects1);
ArrayList<Object> objects2 = new ArrayList<>();
objects2.add("data1");
objects2.add("data2");
objects2.add("data3");
map.put("key2", objects2);
Collection<ArrayList<Object>> collections = map.values();
List<Object> list = new ArrayList<>();
for(ArrayList<Object> collection : collections) {
for(Object obj : collection) {
list.add(obj);
}
}
System.out.println(list);
It will print the output as :
[data1, data2, data3, data1, data2, data3]

Storing multiple datatypes in a single HashMap

I want to put an array of int and a String into a HashMap. Is this possible? what is the proper way to that?
This is my HashMap:
Map<String, String> stringMap = new HashMap<>();
stringMap.put("Text","fish" );
stringMap.put("Diet","false");
stringMap.put("CookingTime", "60");
stringMap.put("OptionId", [7,8,8]);
I know this line is wrong - how do I store an array in a HashMap?
stringMap.put("OptionId", [7,8,8]);
You can instantiate an array in java by doing
someMap.put("OptionId", new int[]{7,8,8});
Otherwise you will need a function that returns those values in an array.
For your case: if you want to create a HashMap of multiple datatypes you can use
HashMap<String, Object> map = new HashMap<String, Object>();
You can then put anything you want in
map.put("key1", "A String");
map.put("key2", new int[]{7,8,8});
map.put("key3", 123);
Except now the tricky part is you don't know what is what so you need to use instanceof to parse the map unless you know what type of object is at a key then you can just cast it to that type.
if(map.get("key1") instanceof String)
String s = (String) map.get("key1"); // s = "A String"
or
int[] arr = (int[]) map.get("key2"); // arr = {7,8,8}

Create multi array in Java

This might be a very basic question but I'm not used to work with Java and I would like to create an array / list like this:
6546:{
"Ram":{
24M,
4M,
64M,
...
},
"Cpu":{
2%,
4%,
6%,
...
},
...
}
I've been trying it with LinkedList and so on but end up creating lists of lists and it starts looking very ugly.
This is a very common array in JSON, PHP or even Javascript, what would be the best way to create it by using Java?
You want a List<List<Integer>> or an int[][].
List<List<Integer>> list = new ArrayList<>();
list.add(new ArrayList<>());
list.get(0).add(24);
But perhaps you just want to use something like Gson and store this as JSON.
Or create a class like:
class Data {
private final List<Integer> ram = new ArrayList<>();
private final List<Integer> cpu = new ArrayList<>();
}
Or if you want to avoid creating classes? (Which you shouldn't)
Map<String, List<Integer>> map = new HashMap<>();
map.put("cpu", new ArrayList<>());
map.put("ram", new ArrayList<>());
Array of array you can define like - String[][].
It might be done in that way.
int[][] twoDimTable = new int[size][size];
String[][] twoDimTable = new String[size][size];
or
List<List<Integer> list = new ArrayList<>(); //or
List<List<String> list = new ArrayList<>();
HashMap<Integer, HashMap<String, List<Object>>> looks good.
This looks more like a key/value indexed structure.
One way (of many) to do something equivalent in Java:
Map<Integer, Map<String, String[]>> myData = new Hashtable<Integer, Map<String, String[]>>();
Map<String, String[]> entries = new Hashtable<String, String[]>();
entries.put("Ram", new String[] {"24M", "4M"}); // etc.
entries.put("Cpu", new String[] {"2%", "4%"}); // etc.
myData.put(6546, entries);
This would create an equivalent data structure, and you could index into it in a familiar fashion:
myData.get(6546).get("Ram")[0];
Although that would be VERY bad form, as you should always check for nulls before using the results of .get(x), such as:
Map<String, String[]> gotEntry = myData.get(6546);
if (gotEntry != null) {
String[] dataPoints = gotEntry.get("Ram");
if (dataPoints != null && dataPoints.length > 0) {
String data = dataPoints[0];
}
}
And so on. Hope this helps!
One other more interesting option is to use something like described here where you can define your data as a JSON string, and convert it into Object types later using un/marshalling.

Data structure to store data subject to keys

Which data structure is better to use in order to store the following data?:
"open" => "11:00", "15:00", "19:00"
"close" => "12:00", "17:00","20:00"
I would need to be able to access data in the following way:
dataStructure.get("open").get(0) => "11:00"
sounds you need something like this Map<String, List<String>>
map.get("open") would return List<String> then you can useget(index) of List's method.
Example:
Map<String, List<String>> map = new HashMap<>();(java 7)
Map<String, List<String>> map = new HashMap<List<Stirng>>();(pre java 7)
Consider your first input:
map.get("Open").get(0); would yield 11:00
Basically you can use a Map with parameters String and list to store the above .. Here list would store the number of sub values ......
Map map = new HashMap<String,list>
List list = map.get("key")
list.get(0) // will give the 0th value
If we use from existing data structure you can have a map something like this ..
Map<String,List<String>> myMap=new HashMap<String,List<String>>();
List<String> openList=new ArrayList<String>();
openList.add("11:00");
openList.add("15:00");
openList.add("19:00");
List<String> closeList=new ArrayList<String>();
closeList.add("12:00");
closeList.add("17:00");
closeList.add("20:00");
myMap.put("open",openList);
myMap.put("close",closeList);
Why not just use an array of strings and use open[0], open[1] etc? The same for an array of close strings.

Convert Hash Map to 2D Array

What is the easiest way to convert a HashMap into a 2D array?
HashMap map = new HashMap();
Object[][] arr = new Object[map.size()][2];
Set entries = map.entrySet();
Iterator entriesIterator = entries.iterator();
int i = 0;
while(entriesIterator.hasNext()){
Map.Entry mapping = (Map.Entry) entriesIterator.next();
arr[i][0] = mapping.getKey();
arr[i][1] = mapping.getValue();
i++;
}
This can only be done when the types of both key and value are the same.
Given:
HashMap<String,String> map;
I can create an array from this map with this simple loop:
String[][] array = new String[map.size()][2];
int count = 0;
for(Map.Entry<String,String> entry : map.entrySet()){
array[count][0] = entry.getKey();
array[count][1] = entry.getValue();
count++;
}
How about
Object[][] array = new Object[][]{map.keySet.toArray(), map.entrySet.toArray()};
Or, to be more specific about the types, let's say they're Strings: Set's toArray takes a hint argument, so that
String[][] array = new String[][]{map.keySet.toArray(new String[0]), map.entrySet.toArray(new String[0])};
Edit: I just realized a couple of days later that while this may work by chance, in general it shouldn't. The reason is the intermediate Set; although it is "backed by the map", there seems to be no explicit guarantee that it will iterate in any particular order. Thus the key- and entry-arrays might not be in the same order, which is a disaster for sure!
Using Java 8 stream:
#Test
void testMapToArray() {
Map<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", 2);
Object[][] arr =
map.entrySet().stream()
.map(e -> new Object[]{e.getKey(), e.getValue()})
.toArray(Object[][]::new);
System.out.println(Arrays.deepToString(arr));
}
Output:
[[key1, value1], [key2, 2]]
Iterate over your Map using entrySet, and fill your array record with the Entry object

Categories