Java Collection with index, key and value - java

My question might sound silly, but would like to know whether there are any Collection object in Java that does store index,key and values in a single Collection object?
I have the following:
Enumeration hs = request.getParameterNames();
LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<String, String>();
while (hs.hasMoreElements()) {
linkedHashMap.put(value, request.getParameter(value));
}
The above stores key and value in linkedHashMap, but it doesn't have an index. If it has then I could call by index(pos) and get corresponding key and value.
Edit 1
I would want to conditionally check if index(position) is x then get the corresponding key and value pair and construct a string with query.

As mentioned by others, Java collections does not support this. A workaround is Map<R, Map<C, V>>. But it is too ugly to use.
You can go with Guava. It provides a Table collection type. It has the following format Table<R, C, V>. I haven't tried this but I think this will work for you.
Enumeration hs = request.getParameterNames();
Table<Integer, String, String> table = HashBasedTable.create();
while (hs.hasMoreElements()) {
table.put(index, value, request.getParameter(value));
}
Now, if you want key, value pair at, let's say, index 1. Just do table.row(1). Similarly, to get index, value pairs just do table.column(value).

No Collection in java, will support this.
You need to create a new class IndexedMap inheriting HashMap and store the key object into the
arraylist by overriding put method.
here is the answer(answerd by another user: Adriaan Koster)
how to get the one entry from hashmap without iterating

Maybe you need implementing yourself for achieving this functionality.
public class Param{
private String key;
private String value;
public Param(String key, String value){
this.key = key;
this.value = value;
}
public void setKey(String key){
this.key = key;
}
public String getKey(){
return this.key;
}
public void setValue(String value){
this.value = value;
}
public String getValue(){
return this.value;
}
}
Enumeration hs = request.getParameterNames();
List<Param> list = new ArrayList<Param>();
while (hs.hasMoreElements()) {
String key = hs.nextElement();
list.add(new Param(key, request.getParameter(key)));
}
By doing this, you could get param with an index provided by List API.

Related

Inverting a HashMap

I have a HashMap that converts two Strings to words and then it adds the words to the map. I have it so that one key can point to multiple values. Now I'd like to make a loop that inverts the table so that all values point to keys. Don't bother with a key pointing to multiple values in the inverse.
Map<Word,Set<Word>> map = new HashMap<Word,Set<Word>>();
public void add(Word t, Word m) {
if(map.containsKey(t)) {
Set<Word> newM = map.get(t);
newM.add(m);
} else {
Set<Word> newSet = new HashSet<>();
newSet.add(m);
map.put(t, newSet);
}
}
public void add(String t, String m) {
add(new Word(t), new Word(m));
}
public Dictionary inverse() {
}
The main problem you're facing is the very common misuse of a map. In your case you don't realy have a map. You have something vaguely similar, so you deciced to use a map. What you really have is a Set of DictionaryEntry objects with DidctionaryEntry looking something like this:
public class DisctionaryEntry {
private String word;
private Set<String> translations;
}
using that datastructure and adding a addTranslation(String translation) method to it, I think, your question becomes fairly obvious.

Incompatible types when returning a generic

I'm trying to implement HashMap in Java, but I get this error when trying to return the value. This is the Entry class:
public class Entry<K,V> {
private K key;
private V value;
public Entry next;
public Entry(K key, V value)
{
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
And this is what I want to return:
private Entry[] buckets = new Entry[255];
public V getValue(K key){
int hash = key.hashCode()%buckets.length-1;
Entry currentEntry = buckets[hash];
while (currentEntry!=null)
{
if (currentEntry.getKey().equals(key)){
return currentEntry.getValue(); //error here
}
currentEntry = currentEntry.next;
}
return null;
}
The error I get is Error:(47, 45) java: incompatible types: java.lang.Object cannot be converted to V
Entry has type parameters but you also have an array of Entry. The two don't go together. You have a number of options including:
Remove the type parameters from Entry and use unsafe casts.
Instead of using array, punt to a List of some description.
Do away with the Entry object and use a probing algorithm with Object[] array and unsafe casts.
Use an unsafe cast to initialise buckets.
Replace the entire algorithm with a tree.
I had modified your getValue method signature on line 1 and below works fine for me.
Also added generics on line 3 with Entry value initialization.
Although line 2 code , hash initialization i find poor but cannot comment much until and unless we see your put(K key,V value) method.
public <K> V getValue(K key){ // line 1
int hash = key.hashCode()%buckets.length-1; // line 2
Entry<K, V> currentEntry = buckets[hash]; //line 3
while (currentEntry!=null)
{
if (currentEntry.getKey().equals(key)){
return currentEntry.getValue();
}
currentEntry = currentEntry.next;
}
return null;
}
You need to add generic to your declaration:
Entry<K,V> currentEntry = buckets[hash];

Java - Keeping 2 keys for one value (TreeMap)

I was trying to create a composite key of Type and Name both return String
public String getObjectName() {
return objectName;
}
public String getObjectType() {
return objectType;
}
and would like to store it in Treemap
both objectName and objectType needs to be a single key and the second String i.e value need to be a user specified Value of Type String
what are your suggestions on this?
This is where I'm gonna store the TreeMap
public static void setDomainDocumentationMap(Map<String, String> domainDocumentationMap) {
MMTUtil.domainDocumentationMap = domainDocumentationMap;
One way is to concatenate as shown in other answers. Then you can use them as key, and in value, put whatever user input is.
This leads to Map<String, String> type.
Another way is to create a class for key:
class Key{
private String objectName;
private String objectType;
//TODO write setters here
public String getObjectName(){
return objectName;
}
public String getObjectType(){
return objectType;
}
public String toString(){
return objectName + ":separator:" + objectType;
}
//TODO implement hashcode and equals method
}
Now your map should be: Map<Key, String> and I believe this should be more flexible.
You can concatenate the two prospective keys with a string like "##-#-#-##" or any other string which you are sure won't be there in your data, and make this concatenated string as the 'key' of your map.
In future if you need to retrieve the two key string from the 'key' of the map, just split the map's key using the "##-#-#-##" string.
As TreeMap is ultimately a map only, It will have same structure i.e key and value.
Only thing that is different is :A tree map guarantees that its elements will be sorted in an ascending key order. You want two Strings as composite key then You can Add any separator between these two strings and then add it as a key.
For example if we use # as separator it would be string1#string2 as key and against it there will be it's value stored.
Code Example :
public class Test{
private static final String SEPERATOR ="$$" ;
private String getCompositekey(String key1, String key2)
{
return key1+SEPERATOR+key2;
}
public static void main(String[] args){
Map<String,Object> t = new TreeMap<String,Object>();
Test test = new Test();
t.put(test.getCompositekey(test.getObjectName(),test.getObjectType()),VALUEGOESHERE);
}
}

Get key from a HashMap using the value [duplicate]

This question already has answers here:
Java Hashmap: How to get key from value?
(39 answers)
Closed 5 years ago.
I want to get the key of a HashMap using the value.
hashmap = new HashMap<String, Object>();
haspmap.put("one", 100);
haspmap.put("two", 200);
Which means i want a function that will take the value 100 and will return the string one.
It seems that there are a lot of questions here asking the same thing but they don't work for me.
Maybe because i am new with java.
How to do it?
The put method in HashMap is defined like this:
Object put(Object key, Object value)
key is the first parameter, so in your put, "one" is the key. You can't easily look up by value in a HashMap, if you really want to do that, it would be a linear search done by calling entrySet(), like this:
for (Map.Entry<Object, Object> e : hashmap.entrySet()) {
Object key = e.getKey();
Object value = e.getValue();
}
However, that's O(n) and kind of defeats the purpose of using a HashMap unless you only need to do it rarely. If you really want to be able to look up by key or value frequently, core Java doesn't have anything for you, but something like BiMap from the Google Collections is what you want.
We can get KEY from VALUE. Below is a sample code_
public class Main {
public static void main(String[] args) {
Map map = new HashMap();
map.put("key_1","one");
map.put("key_2","two");
map.put("key_3","three");
map.put("key_4","four");
System.out.println(getKeyFromValue(map,"four"));
}
public static Object getKeyFromValue(Map hm, Object value) {
for (Object o : hm.keySet()) {
if (hm.get(o).equals(value)) {
return o;
}
}
return null;
}
}
I hope this will help everyone.
If you need only that, simply use put(100, "one"). Note that the key is the first argument, and the value is the 2nd.
If you need to be able to get by both the key and the value, use BiMap (from guava)
You have it reversed. The 100 should be the first parameter (it's the key) and the "one" should be the second parameter (it's the value).
Read the javadoc for HashMap and that might help you: HashMap
To get the value, use hashmap.get(100).
You mixed the keys and the values.
Hashmap <Integer,String> hashmap = new HashMap<Integer, String>();
hashmap.put(100, "one");
hashmap.put(200, "two");
Afterwards a
hashmap.get(100);
will give you "one"
if you what to obtain "ONE" by giving in 100 then
initialize hash map by
hashmap = new HashMap<Object,String>();
haspmap.put(100,"one");
and retrieve value by
hashMap.get(100)
hope that helps.
public class Class1 {
private String extref="MY";
public String getExtref() {
return extref;
}
public String setExtref(String extref) {
return this.extref = extref;
}
public static void main(String[] args) {
Class1 obj=new Class1();
String value=obj.setExtref("AFF");
int returnedValue=getMethod(value);
System.out.println(returnedValue);
}
/**
* #param value
* #return
*/
private static int getMethod(String value) {
HashMap<Integer, String> hashmap1 = new HashMap<Integer, String>();
hashmap1.put(1,"MY");
hashmap1.put(2,"AFF");
if (hashmap1.containsValue(value))
{
for (Map.Entry<Integer,String> e : hashmap1.entrySet()) {
Integer key = e.getKey();
Object value2 = e.getValue();
if ((value2.toString()).equalsIgnoreCase(value))
{
return key;
}
}
}
return 0;
}
}
If you are not bound to use Hashmap, I would advise to use pair< T,T >.
The individual elements can be accessed by first and second calls.
Have a look at this http://www.cplusplus.com/reference/utility/pair/
I used it here : http://codeforces.com/contest/507/submission/9531943

how to swap key in map?

is there a way to sort this numbers stored in a string variable?
TreeMap<String,List<QBFElement>> qbfElementMap = new TreeMap<String, List<QBFElement>>();
this is the map where the key is :
27525-1813,
27525-3989,
27525-4083,
27525-4670,
27525-4911,
27526-558,
27526-1303,
27526-3641,
27526-4102,
27527-683,
27527-2411,
27527-4342
this is the list of keys and the value for each of the key is a list.
now, how can i sort this key in ascending order by number.
ex. if i want to sort : 1,2,11,20,31,3,10
i want to have as output is : 1,2,3,10,11,20,31
but when i use the autosort of treemap the output goes : 1,10,11,2,20,3,31
how can i sort it in ascending order by numeric?
and the language is java :) thank you:)
The keys in your map are not Integer but String values. That's why the key's are sorted like observed.
Either change the Map to
TreeMap<Long,List<QBFElement>> qbfElementMap
or create it with a specialized Comparatorthat will provide the expected numerical order for the String type keys.
A mapping from your String values to Longs could be done like this:
private Long convertToLongTypeKey(String key) {
String[] parts = key.split("-");
// next lines assumes, that the second part is in range 0...9999
return Long.parseLong(parts[0]) * 10000 + Long.parseLong(parts[1]);
}
An implementation of Comparator<String> could use the same mapping to create a numerical comparision of two String based keys:
new TreeMap<String,List<QBFElement>>(new Comparator<String>(){
#Override
public int compare(String key1, String key2) {
String[] parts1 = key1.split("-");
Long long1 = Long.parseLong(parts1[0]) * 10000 + Long.parseLong(parts1[1]);
String[] parts2 = key2.split("-");
Long long2 = Long.parseLong(parts2[0]) * 10000 + Long.parseLong(parts2[1]);
return long1.compareTo(long2);
}
});
You can change the way that the TreeMap sorts its keys by providing a custom comparator to the constructor. If you want, you can define a new Comparator that compares strings by breaking them up into numeric components.
It seems like a better idea, though, would be to not use Strings as your keys. The data you're using as keys is clearly not textual - it's numeric - and you might want to define a custom type to represent it. For example:
public class KeyType implements Comparable<KeyType> {
private final int first;
private final int second;
public KeyType(int first, int second) {
this.first = first;
this.second = second;
}
#Override
public boolean equals(Object other) {
if (!(other instanceof KeyType)) return false;
KeyType realOther = (KeyType) other;
return realOther.first == first && realOther.second == second;
}
#Override
public int hashCode() {
return first + 31 * second;
}
public int compareTo(KeyType other) {
if (first != other.first)
return first - other.first;
return second - other.second;
}
}
This approach is the most expressive and robust. It gives you better access to the individual fields of the keys you're using, and also prevents you from adding nonsensical keys into the map like the string "Lalalalala". I'd strongly suggest using this approach, or at least one like it. The type system is your friend.
A TreeMap can take a custom comparator for custom sorting. Write a comparator that sorts the keys the way you want and use it when you create the treemap
TreeMap<String,List<QBFElement>> qbfElementMap = new TreeMap<String, List<QBFElement>>(myComparator);

Categories

Resources