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]
Related
I have Cache declared as Map:
private Cache<String,Object> operatingParametersCache;
I am getting data from service class and I am putting into Cache:
List<OperatingParametersDTO> objList=this.operatingParamService.getOperatingParamDTO();
operatingParametersCache = cacheManager
.createCache("cacheOfOperatingService", CacheConfigurationBuilder
.newCacheConfigurationBuilder(
String.class,Object.class,
ResourcePoolsBuilder.heap(100000)).withExpiry(Expirations.timeToLiveExpiration(Duration.of(60000,
TimeUnit.SECONDS))));
operatingParametersCache.put("CACHE_OPERATING_PARAMETER",objList);
I tried to get the values from the Cache using:
List<Object> operatingvalues = new ArrayList<>();
operatingParametersCache.forEach(entry -> operatingvalues.add(entry.getValue()));
System.out.println(operatingvalues);
I want to convert this List<Object> to List<OperatingParametersDTO> ,so I tried to convert using :
List<OperatingParametersDTO> listA = new ArrayList<OperatingParametersDTO>(operatingvalues);
But I got : Cannot resolve constructor 'ArrayList(java.util.List)'
The easiest way would be to declare a list with proper type:
List<OperatingParametersDTO> operatingvalues = new ArrayList<>();
and cast:
operatingParametersCache.forEach(entry -> operatingvalues.addAll(((List) entry.getValue()).stream().map(el -> (OperatingParametersDTO) el).collect(Collectors.toList())));
You can also cast every single element:
List<OperatingParametersDTO> listA = operatingvalues.stream()
.map(el -> (OperatingParametersDTO) el)
.collect(Collectors.toList());
You cannot cast collection of one type to collection of other type, more details here.
You can use FlatMap here:
// Dummy Values (I have created 2 fields id and name)
List<OperatingParametersDTO> objList = new ArrayList<>();
objList.add(new OperatingParametersDTO(1, "ABC"));
objList.add(new OperatingParametersDTO(2, "DEF"));
objList.add(new OperatingParametersDTO(3, "GHI"));
// Adding List to Map
Map<String, Object> operatingParametersCache = new HashMap<>();
operatingParametersCache.put("CACHE_OPERATING_PARAMETER", objList);
// Converting List<Object> to List<OperatingParametersDTO> and printing
List<OperatingParametersDTO> listA = operatingParametersCache.values().stream().map(e -> (List<OperatingParametersDTO>) e).flatMap(List::stream).collect(Collectors.toList());
System.out.println(listA);
Output:
[OperatingParametersDTO{id=1, name='ABC'}, OperatingParametersDTO{id=2, name='DEF'}, OperatingParametersDTO{id=3, name='GHI'}]
I have 4 separate hashmaps all of the same type. I would like to merge the values of them all into a single list. I know how to set a List to hashMapOne.values(), but this doesn't help me here since I need to add all values from all 4 lists. Can I do this without looping and individually adding each one?
HashMap<String, MyEntity> hashMapOne = new HashMap<String, MyEntity>();
HashMap<String, MyEntity> hashMapTwo = new HashMap<String, MyEntity>();
HashMap<String, MyEntity> hashMapThree = new HashMap<String, MyEntity>();
HashMap<String, MyEntity> hashMapFour = new HashMap<String, MyEntity>();
List<MyEntity> finalList = new ArrayList<MyEntity>();
List<MyEntity> finalList = new ArrayList<MyEntity>();
finalList.addAll(hashMapOne.values());
finalList.addAll(hashMapTwo.values());
finalList.addAll(hashMapThree.values());
finalList.addAll(hashMapFour.values());
If I were you, I'd just use Stream#of for all Map#values, and then call Stream#flatMap and Stream#collect to transform it to a List:
List<MyEntity> finalList = Stream.of(hashMapOne.values(), hashMapTwo.values(),
hashMapThree.values(), hashMapFour.values())
.flatMap(Collection::stream)
.collect(Collectors.toList());
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.
ArrayList<Object> list = new ArrayList<Object>();
list.add(1);
list.add("Java");
list.add(3.14);
System.out.println(list.toString());
I tried:
ArrayList<String> list2 = (String)list;
But it gave me a compile error.
Since this is actually not a list of strings, the easiest way is to loop over it and convert each item into a new list of strings yourself:
List<String> strings = list.stream()
.map(object -> Objects.toString(object, null))
.toList();
Or when you're not on Java 16 yet:
List<String> strings = list.stream()
.map(object -> Objects.toString(object, null))
.collect(Collectors.toList());
Or when you're not on Java 8 yet:
List<String> strings = new ArrayList<>(list.size());
for (Object object : list) {
strings.add(Objects.toString(object, null));
}
Or when you're not on Java 7 yet:
List<String> strings = new ArrayList<String>(list.size());
for (Object object : list) {
strings.add(object != null ? object.toString() : null);
}
Note that you should be declaring against the interface (java.util.List in this case), not the implementation.
It's not safe to do that!
Imagine if you had:
ArrayList<Object> list = new ArrayList<Object>();
list.add(new Employee("Jonh"));
list.add(new Car("BMW","M3"));
list.add(new Chocolate("Twix"));
It wouldn't make sense to convert the list of those Objects to any type.
Using Java 8 you can do:
List<Object> list = ...;
List<String> strList = list.stream()
.map( Object::toString )
.collect( Collectors.toList() );
You can use wildcard to do this as following
ArrayList<String> strList = (ArrayList<String>)(ArrayList<?>)(list);
If you want to do it the dirty way, try this.
#SuppressWarnings("unchecked")
public ArrayList<String> convert(ArrayList<Object> a) {
return (ArrayList) a;
}
Advantage: here you save time by not iterating over all objects.
Disadvantage: may produce a hole in your foot.
Using guava:
List<String> stringList=Lists.transform(list,new Function<Object,String>(){
#Override
public String apply(Object arg0) {
if(arg0!=null)
return arg0.toString();
else
return "null";
}
});
Here is another alternative using Guava
List<Object> lst ...
List<String> ls = Lists.transform(lst, Functions.toStringFunction());
Your code ArrayList<String> list2 = (String)list; does not compile because list2 is not of type String. But that is not the only problem.
Using Java 8 lambda:
ArrayList<Object> obj = new ArrayList<>();
obj.add(1);
obj.add("Java");
obj.add(3.14);
ArrayList<String> list = new ArrayList<>();
obj.forEach((xx) -> list.add(String.valueOf(xx)));
With Java Generics Takes a list of X and returns a list of T that extends or implements X, Sweet!
// the cast is is actually checked via the method API
#SuppressWarnings("unchecked")
public static <T extends X, X> ArrayList<T> convertToClazz(ArrayList<X> from, Class<X> inClazz, Class<T> outClazz) {
ArrayList<T> to = new ArrayList<T>();
for (X data : from) {
to.add((T) data);
}
return to;
}
A simple solution:
List<Object> lst =listOfTypeObject;
ArrayList<String> aryLst = new ArrayList<String>();
for (int i = 0; i < lst.size(); i++) {
aryLst.add(lst.get(i).toString());
}
Note: this works when the list contains all the elements of datatype String.
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