Initializing an array of pairs in Java - java

I would like to initialize an Array of pairs but my way is not fully correct.
Here how I first wrote it:
Pair<String, Integer>[] pair = new Pair[5];
It is accepted and it works but there is still the following warning:
"Unchecked assignment: 'android.util.Pair[]' to 'android.util.Pair<Java.lang.String, Java.lang.Integer>[]'...
I already tried to do like this:
Pair<String, Integer>[] pair = new Pair<String, Integer>[5];
but it doesn't work.

It is because of the nature of generics.
My suggestion is to drop the idea of using arrays directly, and use a List<Pair<String, Integer>> instead. Under the hood, it uses an array anyway, but a List is more flexible.
List<Pair<String, Integer>> list = new ArrayList<Pair<String, Integer>>();
// You don't have to know its size on creation, it may resize dynamically
or shorter:
List<Pair<String, Integer>> list = new ArrayList<>();
You can then retrieve its elements using list.get(index) whereas you would use list[index] with an array.

You can not create an array of generified type, in this case Pair. That's why your first solution works, because you did not specify the concrete type of Pair.
Technically, you can create an array, Generic arrays in Java, but it's not reccomended.

Related

Memory assignement for Map<String,List<String>>

When we do Map<String,List<String>> = new HashMap<String, List<String>>();
it creates an empty map but is the List inside the map empty as well or is it a null value?
To a certain degree, this depends on the collection type you are using. A hashmap or hashset will not allocate any space for objects that will potentially be added later on. So you only carry the "cost" for exactly that one map or set object when creating it.
Whereas for ArrayList, that is different - they are created using an initial capacity (10 by default); meaning that creating an ArrayList<String> will allocate for an array of strings (String[10] in that sense). So, HashMap<String, List<String>> is "cheaper" than List<Map<Whatever, NotOfInterest>>.
On the other hand: this is really not something to worry about. Unless you are working in "embedded computing" (or you are dealing with millions of objects all the time), you should much more worry about good OO designs instead of memory (or performance) cost of java collections.
Your code:
Map<String,List<String>> = new HashMap<String, List<String>>();
pertains only to the instantiation of a parameterized HashMap. You are using generics to enforce generic types, which states that the TYPE for key must be a String and the TYPE value must be a List<String>. There is no List<String> in memory until you begin adding separately created List<String> objects into to your map. This would look like this:
Map<String, List<String>> myMap = new HashMap<>();//BTW, You only need to parameterize the object declaration since Java 7
List<String> names = new ArrayList<String>();
names.add("Betty");
names.add("Bob");
names.add("Jessica");
names.add("Jim");
myMap.put("names", names);//Where "names" is your key and names is your value.
You can proceed to continue adding more lists to your map from there.
Accepted answer: When you instantiate a collection, it is empty. Any initial capacity it has are of null values, so there are no Lists in this case. – Zircon

Quick way to search through arrayList

I have an arraylist Arraylist<String[]> and I am trying to find a quick way of looking for a specific value on a specific index of the String[]. My ArrayList is always going to contain String[] of length 2. And what I want to do is look through the ArrayList for any String[] that has a specific value i.e. str[1]="value". I know that I can iterate through the ArrayList taking every single element (String[]) and then looking for the value using str[1].equals("value") but I was wondering if there is a quicker way of doing it by maybe using contains() of the ArrayList or something.
thanks
PS: I don't know the value of the first element of my array (str[0]) so I cannot construct a new String[] and check if the ArrayList contains that
If you look into ArrrayList#contains - you will see, that this method also iterates through all elements.
You could use a parallelStream - so that the ArrayList can be searched by more threads.
List<String[]> listToSearchIn = new ArrayList<String[]>();
List<String[]> matches = listToSearchIn.parallelStream()
.filter((element) -> element[1].equals("value"))
.collect(Collectors.toList());
LinkedHashMap
How about using a LinkedHashMap<String, String[]> instead of the ArrayList? The key would be the String[1] value. Linked because that gives you predictable iteration order.
An auxiliary Map
Or you could create a Map<String, Integer> where the key is the String[1] value and the value is the index of your String[] in the ArrayList.
ArrayList<String[]> al = new ArrayList<>();
Map<String, Integer> alIndexMap = new HashMap<>();
// ...
Integer nextIndex = al.size();
al.add(someStringArray);
alIndexMap.put(someStringArray[1], nextIndex);
If you keep al and alIndexMap in sync all the time, you'll always know where in al is the array that you're looking for.
Guava BiMap
Google's Guava has some classes that implement their BiMap interface. It's like a Map, but it works both ways, i.e. you can use the value as a key if you want.
Unless your ArrayList is sorted then O(n) efficiency is the best you can do. Unless by "quick way" you mean a method which does the iteration for you. Even in this scenario the answer is no since you're wanting to check data inside the String[] objects themselves.

How to initiate multidimensional arraylist with different objects?

I'm having trouble trying to initiate an arraylist in which the first column I want to be a string, and the second column be a custom object.
For example column [0] be String, and column[1] be an Integer. Convention attempts of creating a multidimensional arraylist as in those used by int[][] or String[][] don't seem to work :( I would welcome any help. At this point I don't think it's something java allows. I can make it work for just one type of object but it's not what I want. Thanks!
Do you need an arraylist? You could create a Map<String, Object> or Map<String, Integer> or whatever you need..
Sure it does, but you weaken/eliminate type-checking:
Map myMap<String>, Integer> myData = new HashMap<String, Integer>();
Now your list of strings can be retrieved by myMap.keySet() and values can be retrieved by myMap.values(). Each of these return a Set, which you can easily convert to a List using the following code:
List<String> strings = new ArrayList<String>(myMap.keySet()); // get your strings
List<Integer> numbers = new ArrayList<Integer>(myMap.values(); // get your numbers
Good luck and if you should run into problems, do leave a comment.
Arrays are geared towards one specific type of thing - be they Object or String or int. Despite the fact that you're adding multiple dimensions to them, they still only hold one type of information.
What you would rather have is a mapping between two objects. This allows you to do the following:
Associate any key to a particular value
Eliminate duplicate key entries
Be much easier to access instead of array indexing
Here's an example. Say your custom object is a Cat, and you want to map the name of the owner to a particular Cat. You create a new instance of a Map.
Map<String, Cat> catOwners = new HashMap<>();
You can then put elements into it...
catOwners.put("Jamie", new Cat("Tycho"));
...and retrieve them with relative ease.
Cat currentCat = catOwners.get("Jamie"); // gets Jamie's cat
if you really want to, you can even iterate over them using the Map.Entry object provided with all Maps:
for(Map.Entry<String, Cat> element : catOwners.entrySet()) {
System.out.println(element.getKey()
+ " owns " + element.getValue().getName());
}
What you can do is use the generic Object type, and cast accordingly.

Java - getting value from an array using string

I need to make an int array using Strings instead of ints.
EX: int["number2"] = 0; instead of int[2] = 0;
Does anyone know how to do this?
Thanks for your time.
you could use a HashMap - see here for more info!
Java doesn't support associative arrays, but you could use a HashMap:
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("key1", 25);
map.put("key2", 4589);
map.get("key1") will return 25.
You are not looking for an array but for an associative array.
In Java, in practice, every class that implements Map can be used as an associative container, since they can map keys to values (TreeMap<K,V>, HashMap<K,V>, and so on)
This syntax looks very like a map in Groovy, In Java, you could use something like a Map<String, Integer>.

Multidimensional Array with different types in java

I want to store a data structure thats a table with one column Strings and another column of Ints.
List<Entry<String, Integer>> li = new LinkedList<Entry<String, Integer>>();
would do the job for a list but I would rather have the performance of and need the memory of an array.
I tried
Entry<String, Integer>[] = new Entry<String, Integer>[10];
but that doesn't seem to work.
Is Entry the right datatype to use?
Write a class that represents your tuple and use an array (or a List) of that type. Don't eschew classes, they are your friends!
And what exactly do you mean by "the performance of an array"? Arrays are not necessarily faster than List implementations.
Think of inserting an element at the position 0: A LinkedList can do it in O(1). To get the same effect in an array, you'd have to do an O(n) operation (recreating the array and copying all existing values).
If you really need an array of generic types, you can do this:
Entry<String, Integer>[] array = new Entry[10];
It gives you a compilation warning though. You can read more about it here:
http://www.devarticles.com/c/a/Java/Wildcards-Arrays-and-Generics-in-Java/2/
I don't know what is not working, but:
you have to give a name to your array.
you can't construct arrays with generic types
don't forget Entry is an interface.
So, this:
Entry<String, Integer>[] = new Entry<String, Integer>[10];
Should be this:
Entry<String, Integer>[] entries = new Entry[10];
Hope this helps!
Maybe you can just use ArrayList, shouldn't be much difference in performance compared to a plain array.
Use this,
List<Entry<String, Integer>> li = new ArrayList<Entry<String, Integer>>();

Categories

Resources