How to retrieve key & values from hashmap - java

I am trying to insert the values to hash map through object, and i want to check if the values are inserted in to hash map. so i am using this code but in runtime i am not able to get any output.
How to resolve this?
Code:
import java.util.*;
import java.io.*;
import java.lang.*;
public class TaskList
{
private static HashMap<Integer, Object[]> dataz = new HashMap<Integer,Object[]>();
private static HashMap<Integer, Object[]> screen_dataz = new HashMap<Integer,Object[]>();
public final static Object[][] longValues = {{"10", "kstc-proc", "10.10.10.10.10.","5","O"},{"11", "proc-lvk1", "12.1.2.","4","O"},{"13", "trng-lvk1", "4.6.1.","3","O"}};
private static String sl,pid,tid,mval,status;
public static void main(String args[])
{
addTask();
}
public static void addTask()
{
for (int k=0; k<longValues.length; k++)
{
screen_dataz.put(k,longValues);
}
Set mapSet = (Set) screen_dataz.entrySet();
Iterator mapIterator = mapSet.iterator();
while (mapIterator.hasNext())
{
Map.Entry mapEntry = (Map.Entry) mapIterator.next();
String keyValue = (String) mapEntry.getKey();
String value = (String) mapEntry.getValue();
System.out.println(value);
}
}
}

First, you must add a row of the longValues matrix to the map, and not the whole matrix:
for (int k=0; k<longValues.length; k++)
{
screen_dataz.put(k,longValues[k]);
}
Then, while iterating extract the value as Object[] and not String, and key as Integer
while (mapIterator.hasNext())
{
Map.Entry mapEntry = (Map.Entry) mapIterator.next();
Integer keyValue = (Integer) mapEntry.getKey();
Object[] value = (Object[]) mapEntry.getValue();
//iterate over the array and print each value
for (int i=0; i<value.length; i++) {
System.out.print(value[i] + " ");
}
System.out.println();
}

Your code with a few fixes/improvements:
do not use casting when using generics
the loop adding elements to screen_dataz was always adding the same object
the value stored in the map is an array which means it will not be printed as you expect with a simple call to toString()
public class TaskList {
private static HashMap<Integer, String[]> dataz = new HashMap<Integer, String[]>();
private static HashMap<Integer, String[]> screen_dataz = new HashMap<Integer, String[]>();
public final static String[][] longValues = {
{ "10", "kstc-proc", "10.10.10.10.10.", "5", "O" },
{ "11", "proc-lvk1", "12.1.2.", "4", "O" },
{ "13", "trng-lvk1", "4.6.1.", "3", "O" } };
private static String sl, pid, tid, mval, status;
public static void main(String args[]) {
addTask();
}
public static void addTask() {
for (int k = 0; k < longValues.length; k++) {
screen_dataz.put(k, longValues[k]);
}
Set<Entry<Integer, String[]>> mapSet = screen_dataz.entrySet();
Iterator<Entry<Integer, String[]>> mapIterator = mapSet.iterator();
while (mapIterator.hasNext()) {
Entry<Integer, String[]> mapEntry = mapIterator.next();
Integer keyValue = mapEntry.getKey();
String[] value = mapEntry.getValue();
System.out.println(Arrays.toString(value));
}
}
}

One correction in your code:
You may want to update your for loop
as
for (int k=0; k<longValues.length; k++)
{
screen_dataz.put(k,longValues[k]);
}

First, change your for loop to populate to screen_dataz like this.
for (int k=0; k<longValues.length; k++)
{
screen_dataz.put(k,longValues[k]);
}
Next, make the below change:-
String keyValue = mapEntry.getKey().toString();
String value = Arrays.asList((Object[])mapEntry.getValue()).toString();
This will print your value properly.

Quite a few things to comment about this code.
First, the generic arguments of the parameterized type are incorrect. The map is currently storing Map<Long,Object[]> however objects of type Object[][] are added to the Map. I assume you want to enter each Object[] as a separate Entry in the Map.
for (int k=0; k<longValues.length; k++)
{
screen_dataz.put(k,longValues[k]);
}
The second piece to look at is the iteration over the Map entries. Instead of using the Iterator use a for..each loop.
for(Entry<Integer,Object[]> entry: screen_dataz.entrySet()){
//repetitive task
}
Final Output
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class TaskList
{
private static HashMap<Integer, Object[]> dataz = new HashMap<Integer,Object[]>();
private static HashMap<Integer, Object[]> screen_dataz = new HashMap<Integer,Object[]>();
public final static Object[][] longValues = {{"10", "kstc-proc", "10.10.10.10.10.","5","O"},{"11", "proc-lvk1", "12.1.2.","4","O"},{"13", "trng-lvk1", "4.6.1.","3","O"}};
private static String sl,pid,tid,mval,status;
public static void main(String args[])
{
addTask();
}
public static void addTask()
{
for (int k=0; k<longValues.length; k++)
{
screen_dataz.put(k,longValues[k]);
}
for(Entry<Integer,Object[]> entry: screen_dataz.entrySet()){
System.out.println(entry.getKey());
for(Object obj: entry.getValue()){
System.out.println(obj.toString());
}
}
}
}

I think using screen_dataz.put(k,longValues[k]); in a loop will help you.
You could also use an Iterator for this.

Related

Java identifying generic container element type

What I am trying to achieve is a map of generic lists that I can then serialize. I have achieved this but probably not in the best way, anyway I don't understand one point which I describe further below.
Basically I don't see how mClass ends up being "[Ljava.lang.Integer" i.e. Integer[] and not only "java.lang.Integer".
Edit: In order to make my question clear. I don't understand why mClass is Integer[] when I instantiated the class with GenericArrayData< Integer>, i.e. I was expecting Integer. Thanks
import java.util.HashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import junit.framework.Assert;
import org.junit.Test;
public class TestDataCollectorTest {
public class GenericArrayData<T> {
public Class mClass;
public CopyOnWriteArrayList<T[]> data;
public GenericArrayData(Class<T> type) {
mClass = type;
data = new CopyOnWriteArrayList<>();
}
}
public <T> void logGenericArrayData(HashMap<String, GenericArrayData> map, String tag, T[] obj) {
if (map.containsKey(tag)) {
GenericArrayData<T> d = map.get(tag);
d.data.add(obj);
return;
}
System.out.println("Adding log entry named\"" + tag + "\"");
Class k = obj.getClass();
GenericArrayData<T> d = new GenericArrayData<T>(k);
d.data.add(obj);
map.put(tag, d);
}
#Test
public void basics() {
HashMap<String, GenericArrayData> map = new HashMap<>();
GenericArrayData<Integer> list = new GenericArrayData<>(Integer.class);
Integer[][] inputData = new Integer[10][10];
for (int i = 0; i < inputData.length; ++i) {
inputData[i] = new Integer[10];
for (int j = 0; j < inputData[0].length; ++j) {
inputData[i][j] = i * 100 + j;
}
logGenericArrayData(map, "integers", inputData[i]);
}
Assert.assertEquals(1, map.size());
GenericArrayData d = map.get("integers");
Assert.assertEquals(10, d.data.size());
System.out.println(d.mClass);
Integer[] ia = new Integer[0];
System.out.println(ia.getClass());
Assert.assertTrue(ia.getClass() == d.mClass); // I don't quite understand
Integer[][] outputData = new Integer[d.data.size()][];
outputData = (Integer[][]) d.data.toArray(outputData);
Assert.assertEquals(inputData.length, outputData.length);
for (int i = 0; i < inputData.length; ++i) {
Assert.assertEquals(inputData[i], outputData[i]);
}
}
}

Java, add a value to list<pair>

I'm struggling with getting a value from List<Integer> to List<Pair<Integer,Integer>>. Pair is a class written by me which I enclose.
Any ideas how to do it? I would prefer to make a deep copy instead of copying just references. I believe that getting a value from list works fine, the problem is with inserting this value to listPair.
I'd be grateful for any suggestions.
public class Pair<L,R>{
private L key;
private R value;
public Pair(L key, R value)
{
this.key = key;
this.value = value;
}
public L getL() {return key;}
public R getR() {return value;}
public void setL(L key) {this.key = key;}
public void setR(R value) {this.value = value;}
}
It's how I create list(in main()) which I send to function createMatrix
List<Integer> numbersCopy = new ArrayList<Integer>();
public static void createMatrix(List<Integer> list,List<List<Pair<Integer,Integer>>> matrix)
{
Collections.sort(list); //sortuje listÄ™
Collections.reverse(list); //odwraca kolejnosc
int key = 0;
List<Pair<Integer,Integer>> listPair = new ArrayList<Pair<Integer,Integer>>();
for(int i=0;i<list.size();i++)
{
listPair.setR(i) = list.get(i); //elements of list should be saved to value in Pair<Integer, Integer>
}
}
Change your createMatrix method to below
public static void createMatrix(List<Integer> list, List<List<Pair<Integer, Integer>>> matrix) {
List<Integer> numbersCopy = new ArrayList<Integer>();
Collections.sort(list); //sortuje listÄ™
Collections.reverse(list); //odwraca kolejnosc
int key = 0;
List<Pair<Integer,Integer>> listPair = new ArrayList<Pair<Integer,Integer>>();
for(int i=0;i<list.size();i++)
{
listPair.add(new Pair<Integer, Integer>(i, list.get(i))); //elements of list should be saved to value in Pair<Integer, Integer>
}
}
Modified Line in the code is listPair.add(new Pair<Integer, Integer>(i, list.get(i)));
For me it look like a Map.Entry<K,V> is the implementation you look for than you can just call the put(K key, V value) function.
https://docs.oracle.com/javase/7/docs/api/java/util/Map.html
I think more simple is create a Bean with 2 inner fields and put it as
class MyBean{
Integer int0 =null;
Integer int1 =null;
}
List<MyBean> datos = new List<MyBean>();

Java: LinkedHashMaps overlaps over themselves

I want to create a copy of linked hash map and then I want to remove all values (from the List) instead of the first entry. Here is what I got:
LinkedHashMap<String, List<Value>> facetsInCategoriesCopy = new LinkedHashMap<>(facetsInCategories);
if (!facets.equals("something")) {
for (List<Value> value : facetsInCategoriesCopy.values()) {
if (value.size() > 1) {
int nbrOfElements = value.size();
for (int i = nbrOfElements-1; i > 0; i--) {
value.remove(i);
}
}
}
}
After this operation it turns out that facetsInCategories are modified too. Why? And how to solve the issue?
Any help would be appreciated.
I don't have a 50 reputation to add a comment. See this answer Assigning Hashmap to Hashmap
Essentially, the copy constructor you used to make the new map has references to the mutable objects i.e. facetsInCategories and will update that as well when you update the facetsInCategoriesCopy map.
The solution would be to instead do a deep copy instead. I have added test code below, I used String instead of Value
//Test for https://stackoverflow.com/questions/27324315/
public static void testStackO_Q_27324315() {
Map<String, List<String>> facetsInCategories = new LinkedHashMap<String, List<String>>();
String[] values = new String[]{"Test1", "Test2", "Test3"};
List<String> valuesList = new ArrayList<String>(Arrays.asList(values));
facetsInCategories.put("Test", valuesList);
Map temp = Collections.unmodifiableMap(facetsInCategories);
LinkedHashMap<String, List<String>> facetsInCategoriesCopy = (LinkedHashMap<String, List<String>>)deepCopy(temp);
String facets = "test_me";
if (!facets.equals("something")) {
for (List<String> value : facetsInCategoriesCopy.values()) {
if (value.size() > 1) {
int nbrOfElements = value.size();
for (int i = nbrOfElements-1; i > 0; i--) {
value.remove(i);
}
}
}
}
System.out.println(facetsInCategories);
System.out.println(facetsInCategoriesCopy);
}
public static <K1, K2, V> Map<K1, List<V>> deepCopy(
Map<K1, List<V>> original){
Map<K1, List<V>> copy = new LinkedHashMap<K1, List<V>>();
for(Map.Entry<K1, List<V>> entry : original.entrySet()){
copy.put(entry.getKey(), new ArrayList<V>(entry.getValue()));
}
return copy;
}

dynamically creating objects

I have a method that receives an array of strings and I need to create objects with appropriate names.
For example:
public class temp {
public static void main(String[] args){
String[] a=new String[3];
a[0]="first";
a[1]="second";
a[2]="third";
createObjects(a);
}
public static void createObjects(String[] s)
{
//I want to have integers with same names
int s[0],s[1],s[2];
}
}
If I receive ("one","two") I must create:
Object one;
Object two;
If I receive ("boy","girl") I must create:
Object boy;
Object girl;
Any help would be appreciated.
Can't do that in java. You can instead create a Map who's keys are the strings and the values are the objects.
First create Map which contains the key as String representation of Integers.
public class Temp {
static Map<String, Integer> lMap;
static {
lMap = new HashMap<String, Integer>();
lMap.put("first", 1);
lMap.put("second", 2);
lMap.put("third", 3);
}
public static void main(String[] args) {
Map<String, Integer> lMap = new HashMap<String, Integer>();
String[] a = new String[3];
a[0] = "first";
a[1] = "second";
a[2] = "third";
Integer[] iArray=createObjects(a);
for(Integer i:iArray){
System.out.println(i);
}
}
public static Integer[] createObjects(String[] s) {
// I want to have integers with same names
Integer[] number = new Integer[s.length];
for (int i = 0; i < s.length; i++) {
number[i] = lMap.get(s[i]);
}
return number;
}
}

calculating the final length

The following code separates the duplicate names into 1 column and sum of numbers associated with the names into the second column.
Like :
Nokia 21
Blackberry 3
Nimbus 30
from the array given in the program.
I want to know the final length of the array that contain these entries. In this case 3. How do i calculate that ?
package keylogger;
import java.util.ArrayList;
import java.util.List;
public class ArrayTester {
private static int finalLength = 0;
private static String Name[][];
private static String data[][] = {
{"Nokia" , "7"},
{"Blackberry" ,"1"},
{"Nimbus","10"},
{"Nokia" , "7"},
{"Blackberry" , "1"},
{"Nimbus","10"},
{"Nokia" , "7"},
{"Blackberry" , "1"},
{"Nimbus","10"}
};
public void calculator() {
Name = new String[data.length][2];
List<String> marked = new ArrayList<String>();
try {
for(int i=0;i<data.length;i++) {
Name[i][0] = data[i][0];
Name[i][1] = data[i][1];
String name = data[i][0];
if(marked.contains(name)) {
continue;
}
marked.add(name);
int k = i + 1;
int v = k;
for (int j = 0; j < data.length - v; j++) {
String s = data[k][0];
if(Name[i][0].equalsIgnoreCase(s)) {
Name[i][0] = s;
Integer z = Integer.parseInt(Name[i][1]) + Integer.parseInt(data[k][1]);
Name[i][1] = z.toString();
}
k++;
}
}
}catch(Exception exc) {
exc.printStackTrace();
}
}
public static void main(String args[]) {
ArrayTester o = new ArrayTester();
o.calculator();
for(String s[] : Name) {
for(String x : s) {
System.out.println(x);
}
}
}
}
As usual, the "problem" is poor coding. Your entire program, properly written, can be reduced to just 3 lines of code (5 if you include defining the array and printing the output):
public static void main(String[] args) {
String data[][] = {{"Nokia", "7"}, {"Blackberry", "1"}, {"Nimbus", "10"},
{"Nokia", "7"}, {"Blackberry", "1"}, {"Nimbus", "10"}, {"Nokia", "7"},
{"Blackberry", "1"}, {"Nimbus", "10"}, {"Zebra", "78"}};
HashMap<String, Integer> totals = new HashMap<String, Integer>();
for (String[] datum : data)
totals.put(datum[0], new Integer(datum[1]) + (totals.containsKey(datum[0]) ? totals.get(datum[0]) : 0));
System.out.println("There are " + totals.size() + " brands: " + totals);
}
Output:
There are 4 brands: {Nimbus=30, Zebra=78, Nokia=21, Blackberry=3}
You can't know it a priori, the size will be known just when you'll have finished splitting the strings and doing your math.
In your example in the end marked.size() will have the size you are looking for but I'd suggest you to directly use a HashMap so that you won't care about searching for existing elements in linear time and then convert it to an array.
Something like:
String[][] names = new String[map.size()];
Set<String> keys = map.keys();
int c = 0;
for (String k : keys)
{
names[c] = new String[2];
names[c][0] = k;
names[c++][1] = map.get(k).toString();
}
As far as I understand it, you want to know the number of distinct names in your array without calling calculator(), right? I don't really know if that makes sense as you still have to go through every entry and compare it with a set. But you could do it with a Set:
private int getNumberOfEntries(String[][] data) {
Set<String> names = new HashSet<String>();
for (int i=0; i<data.length; i++) {
names.add(data[i][1]);
}
return names.size();
}
Now you can just call int n = getNumberOfEntries(data);...
EDIT: Of course it makes more sense to do the sums in the same step, see Bohemians solution for that.

Categories