I need to store different types of DATA inside one same "array" associated to a key (or an ID) in my android application, and I'm wondering if there's a way to create HashMaps (or equivalent dynamic arrays) that have more than one column of content. Like this for example.
HashMap<Integer, String, LatLng, Marker> myHashMap = new HashMap<Integer, String, LatLng, Marker>();
Thanks in advance for any idea.
private class Row {
public Integer i;
public String s;
public LatLng ll;
public Row(Integer i, String s, LatLng ll) {
this.i = i;
this.s = s;
this.ll = ll;
}
}
List<Row> rows = new ArrayList<Row>();
This is semi pseudo code but I think you get the idea
Adding new Rows to the list can be done with
rows.add(new Row(new Integer(1), "a string", new LatLng(51.448495, 5.470877));
Editing a row can be done with
rowIndex = 3;
Row row = rows.get(rowIndex);
row.i = 2; //give a new value
//etc
Edit: replaced pseude code with real code
map is just a key and value so HashMap makes very little sense
Java does not let you define data structured this way. A collection of type Class A should have hold only instance of Class A or its sub type.
EDIT: From the data you have provided seems like you want to process each row from a database table. Most appropriate data structure for it is to have a class with fields that correspond to a database table.
When you fetch a row from the a result set just create an instance of this class.
Class mysqlTuple
{
public Integer id;
public String message;
public LatLng latitude;
public Marker longitude;
}
mysqlTupe [] mysqlTable = new mysqlTupe [];
It depends a lot on what you are trying to achieve
One option is to keep 3 different maps:
Map<String, Integer>
Map<String,Marker>
Map<String,LatLng>
Another option is to make a:
Map<String,Object>
However you will have to 'instanceof' to check the real type, which is not a best practice.
Related
First off, I've only recently started to use Java, so what might seem obvious to others may not appear so to me.
I'm trying to implement a Quiz application and one of the stipulations is that I read the questions from an external file and store the questions in a MAP structure.
I've looked into this and it appears that a MAP stores a key and a value...
Am I right in thinking that I can store an idetifier as the key and then the rest of the information as the value, even though the rest of it consists of 4 elements of two differing data types (2 ints, a string and an array of strings)?
If my assumtion is correct, how would I implement that, as any documentation I have found resembles the following:
HashMap<Integer, String> questionMap = new HashMap<Integer, String>();
Any assistance or nudges in the right direction are greatly appreciated.
The Question class currently consists of (I've remover the getters and setters to save space on here:
public class Question {
public int identifier;
public String type;
public String question;
public String[] options;
public int answer;
}
First create a class to hold your question information, then use it for the values in your Map, e.g.:
HashMap<Integer, Question> questionMap = new HashMap<Integer, Question>();
the rest of it consists of 4 elements of two differing data types (2 ints, a string and an array of strings)?
This sounds like an Object that you'd want to write your own class for
public class Data {
int id: // optional
int a, b;
String c;
String[] d;
}
Then your Map would be of the type <Integer, Data>, and I would suggest a TreeMap if you want ordered questions
Am I right in thinking that I can store an idetifier as the key and
then the rest of the information as the value, even though the rest of
it consists of 4 elements of two differing data types (2 ints, a
string and an array of strings)?
No, both key and value have to be a of a single data type.
What you usually would do in that case is create your own data structure that encapsules your data:
public class Question {
private int id;
private int score;
private String question;
// Constructor, Getters & Setters
//....
}
Then you can use that dataType as a Value
Map<Integer, Question> questionMap = new HashMap<Integer, Quesiton>();
I am very new in java. I want to create a kind of complex array. I think its called list/collection/map...
My data looks like
-item
ref:GH987
size:22
date:1992
-item
ref:98KJ
size:27
date:2000
-item
ref:ZXJ212
size:24
date:1999
I do not prefer to create an item Class and store the 3 instance in an array.
I found something called Map but it really confused me and I don't understand how could I access the values after creating the data. Could you help me how to start with this ?
final Map<String, List<String>> data = new LinkedHashMap<String, List<String>>();
data.put("item", new LinkedList<String>());
You have to create an Item class, that's the whole point of OOP!
Very minimal example:
public class Item {
public String ref;
public int size;
public int date;
public Item(String ref, int size, int date) {
this.ref = ref;
this.size = size;
this.date = date;
}
}
Then it's just a List<Item> and you can access each part with myList.get(i).ref etc:
List<Item> l = new ArrayList<>();
l.add(new Item("GH987", 22, 1992));
l.add(new Item("98KJ", 27, 2000));
...
for (Item it : l)
System.out.println("Ref: "+item.ref+", size: "+item.size+", date: "+item.date);
Now, if you really want to use a Map to store each attribute, you have to think what would be your unique key. Let's suppose it's ref, which is a String:
Map<String,Integer> sizes = new LinkedHashMap<>(); // LinkedHashMap keeps the insert order
Map<String,Integer> dates = new LinkedHashMap<>();
sizes.put("GH987", 22);
dates.put("GH987", 1992);
sizes.put("98KJ", 27);
dates.put("98KJ", 2000);
then it's difficult to access all members as they're not bundled in a single instance:
String ref = "GH987";
System.out.println("Ref: "+ref+", size: "+sizes.get(ref)+", date: "+dates.get(ref))
Here you should realize that if a Map hasn't been updated, it will return null on the value and you'll have to handle consistency yourself. It is also a pain to create so many objects just to store single attributes, which in your case are Number subclasses (e.g. Integer) instead of native types, which are far more efficient.
So do yourself a favor, and create your Item class. Then you can use a Map to quickly access a particular item based on its key, which looks like the ref member:
myMap.put(ref, new Item(ref, size, date));
Item it = myMap.get(ref);
...
Yes you can choose Map with a class and having it's reference as a key for ex
Map<String,Item> map = new HashMap<>();
Assuming reference is unique. You can store values like
map.put(item.getReference(),item);
I have a project where I save some data coming from different channels of a Soap Service, for example:
String_Value Long_timestamp Double_value String_value String_value Int_value
I can have many lines (i.e. 200), with different values, like the one above.
I thought that I could use an ArrayList, however data can have a different structure than the one above, so an ArrayList maybe isn't a good solution in order to retrieve data from it.
For example above I have, after the first two values that are always fixed, 4 values, but in another channel I may have 3, or 5, values. What I want retrieve data, I must know how many values have a particular line, and I think that Arraylist doesn't help me.
What solution could I use?
When you have a need to uniquely identify varying length input, a HashMap usually works quite well. For example, you can have a class:
public class Record
{
private HashMap<String, String> values;
public Record()
{
// create your hashmap.
values = new HashMap<String, String>();
}
public String getData(String key)
{
return values.get(key);
}
public void addData(String key, String value)
{
values.put(key, value);
}
}
With this type of structure, you can save as many different values as you want. What I would do is loop through each value passed from Soap and simply add to the Record, then keep a list of Record objects.
Record rec = new Record();
rec.addData("timestamp", timestamp);
rec.addData("Value", value);
rec.addData("Plans for world domination", dominationPlans);
You could build your classes representing the entities and then build a parser ... If it isn't in a standard format (eg JSON, YAML, ecc...) you have no choice to develop your own parser .
Create a class with fields.
class ClassName{
int numberOfValues;
String dataString;
...
}
Now create an ArrayList of that class like ArrayList<ClassName> and for each record fill that class object with numberOfValues and dataString and add in Arraylist.
I have created a Vector object to store data in Table object as Vector<Table>. Vector<Table> contains components as below.
[Vector<Record> records, String tableName, String keyColumnName, int recordCount, int columnCount]
I need to sort tableName in above Vector to my own order and return Vector<Table> with sorted tableNames for other processes.
How could i do this ?
UPDATED
I have wrote method as below.
private Vector<Table> orderTables(Vector<Table> loadTables) {
ArrayList<String> tableNames = new ArrayList<String>();
for (Table table : loadTables) {
String tblName = table.getTableName();
tableNames.add(tblName);
}
Collections.sort(tableNames, new MyComparable());
return null;
}
But i have no idea about how to write Comparator to this. My own sort order is stored in .properties file. i can read it and get value. but i have no idea about how to compare it.
How could i do it ?
I suggest you use Collections.sort with your own, custom, Comparator.
Just trying to give a pseudocode
TableComparator implements Comparator{
int compare(Table source, Table destination){
//implement your own custom logic of comparison
}
}
Vector<Table> vectorTable = new Vector<Table>();
TableComparator tableComparator = new TableComparator();
Now use this comparator in Collections.sort(vectorTable,tableComparator);
I've got a setup with Spring & Hibernate over MySQL.
I have a MySQL Stored-Procedure I would like to call.
The procedure takes 2 float arguments, and returns a result-set with 3 fields. Integer,Integer,Float.
I created a class which extends spring's StoredProcedure.
This is the execute function:
public Map execute(float longitude, float latiude) {
Map inparams = new HashMap(2);
inparams.put("longitude", (float) longitude);
inparams.put("latitude", (float) latiude);
Map out = execute(inparams);
The problem is that I don't know how to parse the map result.
When I'm debugging, I see that all the result-set is in there, but It arranged in a strange way, and I don't know how to extract the fields.
The best I can do to show you how it looks, is to give you the toString() of out (Map)
Here it is:
{#result-set-1=[{id=4, out1=100, distance=40.9}, {id=5, out1=100,
distance=47.7}, {id=6, out1=100, distance=22.3}, {id=7, out1=100,
distance=27.4}, {id=8, out1=100, distance=22.1}, {id=9, out1=100,
distance=18.3}, {id=10, out1=100, distance=20.1}, {id=11, out1=100,
distance=28.6}, {id=12, out1=100, distance=23.1}], #update-count-1=0}
I'd look in a debugger to see what the types are; IntelliJ could tell me this easily.
It looks like a Map<String, Object> to me. The keys are "#result-set-1" and "#update-count-1".
The value for the first key is a List of Maps, one Map per row returned. The keys are the column names and the values are the returned values.
The value for the second key is an Integer; it's zero because you did a SELECT.
So, in the interest of spelling it out, here's how to extract your results (sorry for the initial coding error):
// Foo is some unknown object that encapsulates each row.
List<Foo> results = new ArrayList<Foo>();
Map<String, Object> rows = (Map<String, Object>) out.get("#result-set-1");
for (Map row : rows) {
int id = row.get("id");
int out1 = row.get("out1");
double distance = row.get("distance");
results.add(new Foo(id, out1, distance));
}
return results;
Since you are using Spring you can use the Jackson ObjectMapper.
It's more simple than the first answer.
class Foo {
private int id;
private int out1;
private double distance;
// getters and setters
}
ObjectMapper objectMapper = new ObjectMapper();
List<Foo> list = objectMapper.convertValue(execute.get("#result-set-1"), new TypeReference<List<Foo>>() {});
I hope that helps even if this question is open for a long time :)