Converting list of objects to key value pair in java - java

I have java list of objects
[["X","10"],["y","20"],["Z","30"]]
How do I convert this to key value pair?
I want it to be
key:value
X:10
y:20
Z:30
Thanks

You can use 'java.util.stream.Collectors' for this. Please refer to the below example
public class KeyValue {
private String key;
private int value;
public KeyValue (String key, int value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public int getValue() {
return value;
}
}
To convert List to Map
List <KeyValue> list = new ArrayList<>();
list.add(new KeyValue("X", 10));
list.add(new KeyValue("Y", 20));
list.add(new KeyValue("Z", 30));
Map<String, Integer> map = list.stream().collect(
Collectors.toMap(kv -> kv.getKey(), kv -> kv.getValue()));

dict( [["X","10"],["y","20"],["Z","30"]])

Related

How to get the index of object by its property in Java list

I would like to get the index of an object in a list by its property in Java.
Example:
List<MyObj> list = new ArrayList<>();
list.add(new MyObj("Ram");
list.add(new MyObj("Girish");
list.add(new MyObj("Ajith");
list.add(new MyObj("Sai");
public class MyObj {
public String name;
public MyObj(String name){
this.name=name;
}
}
Now, I would like to the get the index of an Object which contains the name as "Girish". Please do let me know the code in JAVA.
If you want a solution with stream use this one:
int index = IntStream.range(0, list.size())
.filter(i -> list.get(i).name.equals(searchName))
.findFirst()
.orElse(-1);
In case you have a List, all you can do is to iterate over each element and check required property. This is O(n).
public static int getIndexOf(List<MyObj> list, String name) {
int pos = 0;
for(MyObj myObj : list) {
if(name.equalsIgnoreCase(myObj.name))
return pos;
pos++;
}
return -1;
}
In case you want to increase performance. Then you could implement your own data structure. Note, that key feature is that your key property should be a key of a HashMap and value of HashMap should be index. Then you get O(1) performance.
public static final class IndexList<E> extends AbstractList<E> {
private final Map<Integer, E> indexObj = new HashMap<>();
private final Map<String, Integer> keyIndex = new HashMap<>();
private final Function<E, String> getKey;
public IndexList(Function<E, String> getKey) {
this.getKey = getKey;
}
public int getIndexByKey(String key) {
return keyIndex.get(key);
}
#Override
public int size() {
return keyIndex.size();
}
#Override
public boolean add(E e) {
String key = getKey.apply(e);
if (keyIndex.containsKey(key))
throw new IllegalArgumentException("Key '" + key + "' duplication");
int index = size();
keyIndex.put(key, index);
indexObj.put(index, e);
return true;
}
#Override
public E get(int index) {
return indexObj.get(index);
}
}
Demo:
IndexList<MyObj> list = new IndexList<>(myObj -> myObj.name);
list.add(new MyObj("Ram"));
list.add(new MyObj("Girish"));
list.add(new MyObj("Ajith"));
list.add(new MyObj("Sai"));
System.out.println(list.getIndexByKey("Ajith")); // 2
indexOf() will work if you change the .equals function
I'd suggest just iterating through
int getIndex(String wanted){
for(int i = 0; i<list.size(); i++){
if(list.get(i).name.equals(wanted)){
return i;
}
}
}
indexOf() will return the index of the first occurrence of a value. For example:
int myIndex = list.indexOf("Ram")
(Note though that your arraylist doesn't contain "Ram", it contains an object of type MyObj with a name of "Ram")
Bear in mind ArrayLists start at 0 not one.

Returning the Key in a Map<String,List<Pair<Integer,String>>>

I have defined a collection using the type TreeMap< String, List < Pair < Integer, String >>> in which pair is a class that I defined:
public class Pair<L,R> {
private L l;
private R r;
public Pair(L l, R r) {
this.l = l;
this.r = r;
}
public L getL() {return l;}
public R getR() {return r;}
public void setL(L l){this.l = l;}
public void setR(R r){this.r = r;}
}
I want to return the string (TreeMap key) that is paired with a list that contains a given String value. For example, I have a String "bob" that is stored in one of the pairs in the list, and I want to return the key (string) of the Treemap that is associated with that list of pairs that "bob" is in. How would I go about doing this?
This essentially is a reverse lookup. You have a map of keys associated to values and you want to find that key for which the associated value satisfies some condition. Note that this, in the worse case, will result in the entire table lookup which can be very expensive because you may end up accessing every entry in the map.
For starters, I'd do something very straightforward like below. I have taken liberty to modify the Pair class a little bit. The following prints the key key2 as per your requirements:
public class ReverseLookup {
static class Pair<L,R> {
private L l;
private R r;
public Pair(L l, R r) {
this.l = l;
this.r = r;
}
public L getL() {return l;}
public R getR() {return r;}
public void setL(L l){this.l = l;}
public void setR(R r){this.r = r;}
public static <L, R> Pair<L, R> right(List<Pair<L, R>> pairs, R rVal) {
for (Pair<L, R> pair : pairs) {
if (rVal != null && rVal.equals(pair.getR()))
return pair;
}
return null;
}
}
public static void main(String[] args) {
String lookFor = "bob";
Map<String, List<Pair <Integer, String>>> listOfPairs = new TreeMap<>();
listOfPairs.put(
"key1", Arrays.asList(new Pair("2", "carol"), new Pair(4, "david"))
);
listOfPairs.put(
"key2", Arrays.asList(new Pair("0", "alice"), new Pair(1, "bob"))
);
for (Map.Entry<String, List<Pair<Integer, String>>> entry : listOfPairs.entrySet()) {
// entry is a mapping from string -> list of pairs Integer, String
List<Pair<Integer, String>> pairs = entry.getValue();
if (Pair.right(pairs, lookFor) != null) {
System.out.println(entry.getKey());
}
}
}
}
I would create predicates, working from inside out. I hope you can follow the logic. This will find the first List that has "Bob" and get that key.
Predicate<Pair<Integer, String>> pairHasBobPred = pair -> ((String) pair.getR()).equals("Bob");
Predicate<String> keyHasBobPred = key -> myTree.get(key).stream()
.anyMatch(pairHasBobPred::test);
String keyWithBob = myTree.keySet().stream()
.filter(keyHasBobPred::test)
.findFirst()
.get();

grouping objects according to some fields

i have a List of an Object, with the following characteristics:
Class myObject{
String gender;
String state;
int quantity;
int Salary;
}
List<myObject> myList=new ArrayList<Object>;
As input of the List, i have the following:
and as Output, i want to keep only one occurrence of the object with the same gender and the same state, in the same time sum the quantity and the salsary correspanding, like the following:
my question is how can i loop through myList, find objects with the same gender and the same state,keep only one occurence of them, and sum the quantity and the salary correspanding ??
in other words, for the first and second line (same gender, same state), keep only one line and sum the correspanding quantity and salary
private Collection<MyObject> aggregate(List<MyObject> objects) {
Map<String, MyObject> map = new HashMap<String, MyObject>();
for (MyObject current : objects) {
String key = String.format("%s:%s", current.gender, current.state);
MyObject aggregated = map.get(key);
if (aggregated == null) {
aggregated = new MyObject();
aggregated.gender = current.gender;
aggregated.state = current.state;
map.put(key, aggregated);
}
aggregated.quantity += current.quantity;
aggregated.salary += current.salary;
}
return map.values();
}
Equivalent with Java 8:
private static Collection<myObject> aggregate(List<myObject> objects) {
return objects.stream()
.collect(groupingBy(myObject::genderAndState, reducing(new myObject(), myObject::merge)))
.values();
}
private static myObject merge(myObject o1, myObject o2) {
myObject tmp = new myObject();
tmp.gender = o2.gender;
tmp.state = o2.state;
tmp.quantity= o1.quantity + o2.quantity;
tmp.salary = o1.salary + o2.salary;
return tmp;
}
private static String genderAndState(myObject o) {
return o.gender.concat(o.state);
}

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>();

TreeMap - Dynamic ordering elements based on key

I want to use HashMap with ordering of elements. So I choose TreeMap. Below code gives me strange answer, than what I expected
public class MapTest {
public static class Key implements Comparable<Key>{
private String key;
private int count;
public Key(String key, int count){
this.key = key;
this.count = count;
}
#Override
public int hashCode() {
return key.hashCode();
}
#Override
public boolean equals(Object obj) {
return key.equals(obj);
}
#Override
public int compareTo(Key o) {
return count - o.count;
}
}
public static void main(String[] args) {
Map<Key, Integer> map = new TreeMap<>();
Key c = new Key("c", 4);
map.put(new Key("a", 6), 1);
map.put(new Key("b", 8), 1);
map.put(c, 1);
map.put(new Key("d", 2), 1);
for(Map.Entry<Key, Integer> entry : map.entrySet()){
System.out.println(entry.getKey().key);
}
//map.remove(c);
map.put(c, null);
c.count = 0;
map.put(c, 1);
for(Map.Entry<Key, Integer> entry : map.entrySet()){
System.out.println(entry.getKey().key);
}
}
}
If I use map.remove() and add element, it is ordered. Otherwise it is always returns the element in order
d c a b
Why above code is not working? put(key, null) should delete the value and if new value is inserted it has to be ordered right?
put(key, null) does not remove the key from the map. It is still in the map, just mapping to null. You want to remove(key).
Objects used as keys in a Map should be immutable really. You are modifying the key after you put it into the map - but the map has no mechanism to detect that and move the key so as you realized the key ends up at an invalid location.
This can then confuse the Map to the point that it doesn't think the key is present in the map at all since it goes to look for it where it should be and it isn't there.

Categories