Create multi array in Java - 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.

Related

How to push value in List of Object?

A problem occurred while the Java project was in progress, so I asked a question.
For example, suppose we have this Object in JavaScript.
let testObject = {
'Fruit' : [],
'Food': []
}
I can add a value to the food array.
testObject['Fruit'].push('tomato');
testObject['Food'].unshift('ramen');
Like javascript, java directly pushes a value to a list of objects.
HashMap<String, ArrayList<String>> testObject = new HashMap<>();
testObject.put("Food",new ArrayList<>());
testObject.put("Fruit",new ArrayList<>());
for(T etc : testObject...){
if(etc...equals("Fruit")){
etc..add('tomato');
}else if(etc..equals("Food")){
etc..add('ramen');
}
}
Is there any way other than to declare ArrayList in advance using call by reference and put it in testObject?
As of java 8+ you can try something like this:
Map<String, Collection<String>> food = new HashMap<>();
// ... any code ...
food.computeIfAbsent("fruits", k -> new ArrayList<String>()).add("apple");
Assuming key is present in map
testObject.get("Fruit").add("tomato")
Assuming key may not be present in map
public static void main(String[] args) {
Map<String, List<String>> testObject = new HashMap<>();
testObject.put("A", new ArrayList<>());
testObject.get("A").add("tomato");
testObject.computeIfAbsent("B", k -> new ArrayList<>()).add("tomato");
System.out.println(testObject);
}

How to insert array of objects in Firestore?

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)

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}

Appending data to a subarray instead of having it overwritten with the latest entry

I currently have a Map that is configured as such.
Map<String, ArrayList<Object>> map = new HashMap<String, ArrayList<Object>>();
where the purpose is to be able to have a setup much like the following:
array("foo"->array(1->"aaa",2->"bbb",3->"ccc"),
"bar"->array(1->"aaa",2->"bbb",3->"ccc"),
"bah"->array(1->"aaa",2->"bbb",3->"ccc"),
)
The problem I'm running into is that I can create the root array fine, but it will do the following, using the previous example as illustration
array("foo"->array(3->"ccc"),
"bar"->array(2->"bbb"),
"bah"->array(3->"ccc"),
)
What I'm trying to find out is how I can append the sub array as opposed to having it overwritten. I assume it's easily done I'm just missing something obvious.
What you need is to first check if map has an entry for a particular key. If not, then add an empty arraylist.
After that, get that arraylist from map and add object to that arraylist.
Map<String, ArrayList<Object>> map = new HashMap<String, ArrayList<Object>>();
String first = "FIRST";
if (map.get(first) == null){
map.put(first, new ArrayList<Object>());
}
map.get(first).add(new Object());
If you will print above map, you will get desired output.
Appending to Array's in Java is not possible because they have a fixed length. I suggest you use ArrayList instead.
HashMap<String, ArrayList<Object>> map = new HashMap<String, ArrayList<Object>>();
public void appendToMap(String key, Object o)
{
if(!map.containsKey(key))
{
map.put(key, new ArrayList<Object>());
}
map.get(key).add(o);
}
Afterwards just set your values:
appendToMap("foo", "aaa");
appendToMap("foo", "bbb");
// and so on...
You can just create a method to add to the sub-array, and create it if it doesn't exists :
Map<String, ArrayList<Object>> map = new HashMap<String, ArrayList<Object>>();
addToArray(map, "foo", "aaa");
addToArray(map, "foo", "bbb");
addToArray(map, "foo", "ccc");
addToArray(map, "bar", "aaa");
// ...
And the method would be :
private static void addToArray(final Map<String, ArrayList<Object>> map, final String key, final Object object) {
if (!map.containsKey(key))
map.put(key, new ArrayList<Object>());
map.get(key).add(object);
}
If you only need to store Strings in you array, you can use an ArrayList<String> instead of your ArrayList<Object>.
Switch to String instead of Object (if the list would always contain strings)
Map<String, List<String>> map = new HashMap<String, List<String>>();
Then add to your Map as follows
// check if a List already exists
if ((list = map.get("foo")) == null) { // if !exists,
list = new ArrayList<String>(1); // CREATE a new List
list.add("aaa");
map.put("foo", list); // ADD the new List to Map
} else { // if exists,
list.add("aaa"); // ADD to the existing List
}

Java associative-array

How can I create and fetch associative arrays in Java like I can in PHP?
For example:
$arr[0]['name'] = 'demo';
$arr[0]['fname'] = 'fdemo';
$arr[1]['name'] = 'test';
$arr[1]['fname'] = 'fname';
Java doesn't support associative arrays, however this could easily be achieved using a Map. E.g.,
Map<String, String> map = new HashMap<String, String>();
map.put("name", "demo");
map.put("fname", "fdemo");
// etc
map.get("name"); // returns "demo"
Even more accurate to your example (since you can replace String with any object that meet your needs) would be to declare:
List<Map<String, String>> data = new ArrayList<>();
data.add(0, map);
data.get(0).get("name");
See the official documentation for more information
Java doesn't have associative arrays like PHP does.
There are various solutions for what you are doing, such as using a Map, but it depends on how you want to look up the information. You can easily write a class that holds all your information and store instances of them in an ArrayList.
public class Foo{
public String name, fname;
public Foo(String name, String fname){
this.name = name;
this.fname = fname;
}
}
And then...
List<Foo> foos = new ArrayList<Foo>();
foos.add(new Foo("demo","fdemo"));
foos.add(new Foo("test","fname"));
So you can access them like...
foos.get(0).name;
=> "demo"
You can accomplish this via Maps. Something like
Map<String, String>[] arr = new HashMap<String, String>[2]();
arr[0].put("name", "demo");
But as you start using Java I am sure you will find that if you create a class/model that represents your data will be your best options. I would do
class Person{
String name;
String fname;
}
List<Person> people = new ArrayList<Person>();
Person p = new Person();
p.name = "demo";
p.fname = "fdemo";
people.add(p);
Look at the Map interface, and at the concrete class HashMap.
To create a Map:
Map<String, String> assoc = new HashMap<String, String>();
To add a key-value pair:
assoc.put("name", "demo");
To retrieve the value associated with a key:
assoc.get("name")
And sure, you may create an array of Maps, as it seems to be what you want:
Map<String, String>[] assoc = ...
There is no such thing as associative array in Java. Its closest relative is a Map, which is strongly typed, however has less elegant syntax/API.
This is the closest you can get based on your example:
Map<Integer, Map<String, String>> arr =
org.apache.commons.collections.map.LazyMap.decorate(
new HashMap(), new InstantiateFactory(HashMap.class));
//$arr[0]['name'] = 'demo';
arr.get(0).put("name", "demo");
System.out.println(arr.get(0).get("name"));
System.out.println(arr.get(1).get("name")); //yields null
Well i also was in search of Associative array and found the List of maps as the best solution.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class testHashes {
public static void main(String args[]){
Map<String,String> myMap1 = new HashMap<String, String>();
List<Map<String , String>> myMap = new ArrayList<Map<String,String>>();
myMap1.put("URL", "Val0");
myMap1.put("CRC", "Vla1");
myMap1.put("SIZE", "Vla2");
myMap1.put("PROGRESS", "Vla2");
myMap.add(0,myMap1);
myMap.add(1,myMap1);
for (Map<String, String> map : myMap) {
System.out.println(map.get("URL"));
}
//System.out.println(myMap);
}
}
Java equivalent of Perl's hash
HashMap<Integer, HashMap<String, String>> hash;
Java doesn't have associative arrays, the closest thing you can get is the Map interface
Here's a sample from that page.
import java.util.*;
public class Freq {
public static void main(String[] args) {
Map<String, Integer> m = new HashMap<String, Integer>();
// Initialize frequency table from command line
for (String a : args) {
Integer freq = m.get(a);
m.put(a, (freq == null) ? 1 : freq + 1);
}
System.out.println(m.size() + " distinct words:");
System.out.println(m);
}
}
If run with:
java Freq if it is to be it is up to me to delegate
You'll get:
8 distinct words:
{to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2}
Use ArrayList < Map < String, String > >
Here a code sample :
ArrayList<Map<String, String>> products = new ArrayList<Map<String, String>>();
while (iterator.hasNext()) {
Map<String, String> product = new HashMap<String, String>();
Element currentProduct = iterator.next();
product.put("id",currentProduct.get("id"));
product.put("name" , currentProduct.get("name") );
products.add(product );
}
System.out.println("products : " + products);
Output :
products : [{id=0001, name=prod1}, {id=0002, name=prod2}]
Associative arrays in Java like in PHP :
SlotMap hmap = new SlotHashMap();
String key = "k01";
String value = "123456";
// Add key value
hmap.put( key, value );
// check if key exists key value
if ( hmap.containsKey(key)) {
//.....
}
// loop over hmap
Set mapkeys = hmap.keySet();
for ( Iterator iterator = mapkeys.iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
String value = hmap.get(key);
}
More info, see Class SoftHashMap : https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/util/SoftHashMap.html
Object[][] data = {
{"mykey1", "myval1"},
{"mykey2", "myval2"},
{new Date(), new Integer(1)},
};
Yes, this require iteration for searchting value by key, but if you need all of them, this will be the best choice.
In JDK 1.5 (http://tinyurl.com/3m2lxju) there is even a note: "NOTE: This class is obsolete. New implementations should implement the Map interface, rather than extending this class."
Regards, N.
Actually Java does support associative arrays they are called dictionaries!
Thinking more about it, I would like to throw out tuples as a more general-purpose way of dealing with this problem. While tuples are not native to Java, I use Javatuples to provide me the same functionality which would exist in other languages. An example of how to deal with the question asked is
Map<Pair<Integer, String>, String> arr = new HashMap<Pair<Integer, String>, String>();
Pair p1 = new Pair(0, "name");
arr.put(p1, "demo");
I like this approach because it can be extended to triples and other higher ordered groupings with api provided classes and methods.
Regarding the PHP comment 'No, PHP wouldn't like it'. Actually, PHP would keep on chugging unless you set some very restrictive (for PHP) exception/error levels, (and maybe not even then).
What WILL happen by default is that an access to a non existing variable/out of bounds array element 'unsets' your value that you're assigning to. NO, that is NOT null. PHP has a Perl/C lineage, from what I understand. So there are: unset and non existing variables, values which ARE set but are NULL, Boolean False values, then everything else that standard langauges have. You have to test for those separately, OR choose the RIGHT evaluation built in function/syntax.

Categories