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>();
Related
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"]])
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.
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();
I am trying to use a comparator to sort my List 2 based on List 1.
So the two lists are:
ListA = [2,3,4]
ListB = [8,2,4]
I need to sort list 2 based on list 1.
Expected output:
List1: [2,3,4]
List2: [2,8,4]
Here is the code I am trying
Collections.sort(list1);
Collections.sort(list2,new Comparator<Integer>(){
public int compare(Integer left,Integer right){
return Integer.compare(list1.indexOf(left),list1.indexOf(right));
}
})
Here sorting will be based on index of List1 elements. The comparator above is not working for me Please help?
It's not exactly clear to me from your example what you're trying to do, so this answer might not actually address your question. If what you're trying to do is to apply the sort-order of ListA to both ListA and ListB then you can do it as follows.
Create an auxiliary class that allows you to pair up the two lists with respect to the same index:
private class IntPair implements Comparable<IntPair> {
int i1;
int i2;
public IntPair(int i1, int i2) {
this.i1 = i1;
this.i2 = i2;
}
public int compareTo(IntPair other) {
return Integer.compare(i1, other.i1);
}
}
Then create a new list of IntPair instances from your original lists and sort it.
int size = list1.size();
List<IntPair> aux = new ArrayList(size);
for (int i = 0; i < size; i++) {
aux.add(new IntPair(list1.get(i), list2.get(i)))
}
Collections.sort(aux);
Finally, copy back the values of the resulting pair list onto your original lists.
for (int i = 0; i < size; i++) {
IntPair ip = aux.get(i);
list1.set(i, ip.i1);
list2.set(i, ip.i2);
}
Note that in terms of algorithmic complexity, this approach still is O(nlogn).
This might be a little heavy-weight, but it gets the job done and it's generic.
Essentially, you can zip-up two lists, sort/compare them based off an index, unzip them, and return the result.
This does not modify the list in-place. I tried to give the variables meaningful, but discreet names. Please acknowledge me for clarification.
import java.util.*;
public class SortUtil {
public static void main(String[] args) {
List<Integer> indicies = Arrays.asList(3, 2, 4);
List<Integer> values = Arrays.asList(8, 2, 4);
List<Integer> sorted = doSort(indicies, values, new TupleComparator<Integer>(0, 1) {
#Override
public int doCompare(Integer valueA, Integer valueB) {
return Integer.compare(valueA, valueB);
}
});
System.out.println(sorted); // [2, 8, 4]
}
public static List<Integer> doSort(List<Integer> listA, List<Integer> listB, TupleComparator<Integer> comparator) {
List<Tuple<Integer>> tuples = zip(listA, listB);
Collections.sort(tuples, comparator);
return unzip(tuples, comparator.getValuePos());
}
private static <E> List<E> unzip(List<Tuple<E>> tuples, int index) {
List<E> list = new ArrayList<E>();
for (Tuple<E> tuple : tuples) {
list.add(tuple.getData().get(index));
}
return list;
}
private static <E> List<Tuple<E>> zip(List<E> listA, List<E> listB) {
List<Tuple<E>> listC = new ArrayList<Tuple<E>>();
for (int i = 0; i < listA.size(); i++) {
listC.add(new Tuple<E>(Arrays.asList(listA.get(i), listB.get(i))));
}
return listC;
}
private static abstract class TupleComparator<E> implements Comparator<Tuple<E>> {
private int indexPos;
private int valuePos;
public TupleComparator(int indexPos, int valuePos) {
this.indexPos = indexPos;
this.valuePos = valuePos;
}
public int compare(Tuple<E> left, Tuple<E> right) {
E indexA = left.getData().get(this.getIndexPos());
E indexB = right.getData().get(this.getIndexPos());
return doCompare(indexA, indexB);
}
public int getIndexPos() { return indexPos; }
public int getValuePos() { return valuePos; }
public abstract int doCompare(E valueA, E valueB);
}
private static class Tuple<T> {
private List<T> data;
public Tuple(List<T> data) { this.data = data; }
public List<T> getData() {return data; }
}
}
I have a hashmap of objects. Each object has two attributes (let say int length and int weight).
I want to remove k elements with the smallest length.
What is the efficient way of doing this?
Map<K, V> map = new HashMap<>();
...
Set<K> keys = map.keySet();
TreeSet<K> smallest = new TreeSet<>(new Comparator<K>(){
public int compare(K o1, K o2) {
return o1.getLength() - o2.getLength();
}
});
smallest.addAll(keys);
for(int x = 0; x < num; x++) {
keys.remove(smallest.pollFirst());
}
Where K is your key type, V is your value type, and num is the number of elements you wish to remove.
If you are doing this frequently, it might be a good idea to use a TreeMap in the first place.
The easiest, but certainly not the most efficient is to create an instance of a TreeMap with provided Comparator for your type, putAll() elements from your map to the map you just created and remove k-elements with help of keySet(). In the end a TreeMap will not contain k-smallest elements.
You didn't mention if the attribute you discriminate on is part of the key or the value, if it's the key then teh treemap discussed above is applicbale.
Otherwise If you need to do this often I'd be inclined to implement my own map, delegating everything in the map interface to a hashmap (or appropriate structure0. Override the add/remove and if necessary iterator, then use the add/remove to maintain a sorted list of the values.
This obviously assumes the values don't change and is highly coupled to your problem.
Keep in mind that TreeMap sorts by the natural ordering of its keys. Hence you can create a key with comparable based on the length of it's value. For example (Since I am on Lunch the code isn't perfect but should get you to what you need):
package com.trip.test;
import java.util.SortedMap;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ComparisonTest {
private static Logger logger = LoggerFactory.getLogger(ComparisonTest.class);
private static String[] a = {"1","2","3","4"};
private static String[] b = {"A","B","D"};
private static String[] c = {"1","B","D","1","B","D"};
/**
* #param args
*/
static SortedMap<KeyWithLength, String[]> myMap = new TreeMap<KeyWithLength, String[]>();
static {
myMap.put(new KeyWithLength("a", a.length), a);
myMap.put(new KeyWithLength("b", b.length), b);
myMap.put(new KeyWithLength("c", c.length), c);
}
public static void main(String[] args) {
// print Map
logger.info("Original Map:");
int i = 0;
for (String[] strArray: myMap.values() ){
logger.info(String.format("*** Entry %s: ", i++));
printStrings(strArray);
}
// chop off 2 shortest
chopNShortest(myMap, 2);
// print Map
logger.info("ShortenedMap:");
i = 0;
for (String[] strArray: myMap.values() ){
logger.info(String.format("*** Entry %s: ", i++));
printStrings(strArray);
}
}
static void printStrings(String[] strArray){
StringBuffer buf = new StringBuffer();
for (String str: strArray){
buf.append(String.format("%s, ", str));
}
logger.info(buf.toString());
}
static void chopNShortest(SortedMap<KeyWithLength, String[]> sortedMap, int n) {
// Assuming map is not unmodifiable
if (n <= sortedMap.size()-1){
for (int i = 0; i< n;i++){
sortedMap.remove(sortedMap.firstKey());
}
}
}
}
class KeyWithLength implements Comparable<KeyWithLength> {
private String key;
private Integer length;
public KeyWithLength(String key, int length) {
super();
this.key = key;
this.length = length;
}
public String getKey() {
return key;
}
public int getLength() {
return length;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
KeyWithLength other = (KeyWithLength) obj;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
return true;
}
#Override
public int compareTo(KeyWithLength another) {
// TODO Auto-generated method stub
return compare(this.length, another.length);
}
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
}
The output:
Original Map:
*** Entry 0:
A, B, D,
*** Entry 1:
1, 2, 3, 4,
*** Entry 2:
1, B, D, 1, B, D,
ShortenedMap:
*** Entry 0:
1, B, D, 1, B, D,