Access an index of an array with dynamically generated name - java

I have some Java code which contains some arrays. Say one of them is b. I have a string a whose value points to the names of those arrays at different times. So if a currently contains b, I want to access the 3rd element of b through a. Something which I could have done in Javascript with window[a][2]. is it possible in Java?

Use collections. Looks like you're looking for HashMap
Something like that:
Map<String, List<String>> map = new HashMap<String, List<String>>();

Based on your comments above, I'll give you a pseudo code answer:
Write the handler like this:
public class MyHandler implements YourHandlerInterface {
private String[] array;
public MyHandler(String[] array) {
this.array = array;
}
// your methods that have to access the array.
}
Then, when you can use them somehow like:
fileMenu.addHandler(new MyHandler(fileMenuArray));
editMenu.addHandler(new MyHandler(editMenuArray));
So you don't use dynamically generated variable names and still only have to implement it once.

Related

Android extract array of properties of array of objects

I was wondering if there's an effective way to extract an array of properties from an array of custom class objects. For example if I have something like this:
public class MyClass {
private Double p1;
private String p2;
private MyProperty p3;
public MyClass() {}
}
and in somewhere I have an ArrayList filled with objects of this class:
ArrayList<MyClass> listOfObjects = new ArrayList<>();
and I'd like to get a list of one of the properties:
ArrayList<MyProperty> listOfP3 = new ArrayList<>();
ArrayList<Double> listOfP1 = new ArrayList<>();
All I can think of is iterating through listOfObjects and copying the desired properties one by one to a new array... Is there a better way to do this?
EDIT:
If possible one that works with Java 7 also
Probably the cleanest way to do it is to use Streams. Something like this:
List<String> listOfP2= listOfObjects.stream().map(x->x.getP2()).collect(Collectors.toList());
Of course in MyClass you need to add a getter for those fields.
In Java 8 and higher, you can utilize the stream API (as #Amongalen already answered). There is a different possibility of accessing methods: Instead of x -> x.getP1() you can just write MyClass::getP1:
List<Double> p1List = myObjects.stream().map(MyClass::getP1).collect(Collectors.toList());
List<String> p2List = myObjects.stream().map(MyClass::getP2).collect(Collectors.toList());
List<MyProperty> p3List = myObjects.stream().map(MyClass::getP3).collect(Collectors.toList());

Custom method for ArrayList

Hello I would like to make a custom method for ArrayList class.
So lets say I make a new ArrayList.
ArrayList<String> list = new ArrayList<String>
I would like to make a method I can call on list.
Something like this:
list.myMethod();
What I want to solve with my method is so you can get an Object by Object name and not index inside the ArrayList.
So basically I want to make a method returning following:
list.get(list.indexOf(str));
To sum it up:
ArrayList<String> list= new ArrayList<>();
String str = "asd";
String str2 = "zxc";
list.add(str2);
list.add(str);
System.out.println(list.get(0));
System.out.println(list.get(list.indexOf(str)));
Will print: "asd" "asd".
So instead of writing: list.get(list.indexOf(Object))
I would like to be a able to write list.myMethod(Object) and get the same result. I hope you understand my question. I know this is probably a dumb solution and I could just use a Map. But this is for learning purpose only and nothing I will use.
Custom method >>
public class MyArrayList<E> extends ArrayList<E> {
public E getLastItem(){
return get(size()-1);
}
}
How to use it >>
MyArrayList<String> list= new MyArrayList<>();
String str = "asd";
String str2 = "zxc";
list.add(str2);
list.add(str);
System.out.println(list.getLastItem());
what you need requires to extend the ArrayList classs, but you should consider using instead a
Map<String, Object>
with that approach you can do something like
myMap.get("myObject1");
You should just extend the ArrayList class creating your own with the new method. But the performance would be horrible if your list grow too much. The indexOf method have O(n), so greater is the size of your array longer is the time you have to wait.
May be you should choose a different collection if you want access directly to the element. In your case, it elements stored in the collection are unique, you could use a Set.
On the other hand, a Set does not preserve the insertion order. I don't know if this is a think you have to care of.
And a Set just let you know if the element is contained into the collection.
Another collection that can be of your interest is the Map, this is a key-value collection.
But given that you have only keys this it seems not be your case.

Multidimensional Arrays in Java

Alright, so I've been working with PHP for most of my career and find myself needing to use Java. In my case, the biggest issue I have is creating and manipulating arrays in Java.
Example in PHP:
$cars = array(1 => array("stats"=> array("velocity"=>100,
"acceleration"=>0,
"energy"=>30000,
"distance"=>200
)
),
2 => array("stats"=> array("velocity"=>3,
"acceleration"=>6,
"energy"=>30000,
"distance"=>200)
)
);
I'm trying to re-create this type of array in Java but I'm having trouble with initializing it. Is the array considered a String in this case? And must the size of the array be set prior to creating it? e.g: String[][][] car = new String[][][]?
Exactly as aet said in a comment - if you're considering doing this in java - don't. You're doing it wrong.
You should have a class for Car
public class Car {
private int velocity;
private int acceleration;
private int energy;
private int distance;
//getters and setters, a constructor that gets all the property values ...
}
and then store your cars in some collection. An ArrayList is the easiest way:
List<Car> cars = new ArrayList<Car>();
cars.add(new Car(100,0,30000,200));
cars.add(new Car(3,6,30000,200));
Accessing the list of cars would then look like this:
cars.get(0).getVelocity(); //collection indexes start at 0
I think Java doesn't have TRUE multidimensional arrays. An array which is accessed like a[i][j][k] is simply an array, of arrays, of arrays.
You can try the following construct:
String[][] car = new String [][] { { "X0", "Y0"},
{ "X1", "Y1"},
{ "X2", "Y2"},
{ "X3", "Y3"},
{ "X4", "Y4"} };
1) is that "stats" index nesserly? if not, you can:
Map<String, Integer>[] cars = new HashMap<String, Integer>[your length here];
this will index your cars by numbers, skip the "stats" index, and allow you to index the last integer by string:
int velocityOfSecondCar = cars[1].get("velocity"); //note indexing from 0
2) if "stats" index is nesserly, you would have to go one dimension deeper
What you have in PHP there would typically be represented as nested Map instances in Java. For example:
HashMap<Integer,Map<String,Map<String,Integer>>> data = new HashMap<>();
Then you could get values (assuming all levels of the Hash are populated correctly) by saying:
int velocity = data.get(1).get("stats").get("velocity");
Populating nested maps like this can be complicated, and you would typically use a helper method to make sure all the 'parent' levels are populated before you add a data member.
Yes, lenghts must be provided when initializing an array. Hence, your array would look something like this:
int lenght1=x;
int length2=y;
int lenght3=z;
String[][][] car = new String[lenght1][lenght2][lenght3]
I'm no PHP developer myself, but Classes within the array will obey the OOP rules Java implements in terms of abstraction and inheritance. So when you retrieve the elements you can use their corresponding interfaces whatever the class or interface that contains them are.
On the other hand, if you can't know the array lenghts before the initialization you can use class ArrayList, which is almost like a Vector. This class modify its internal length if new elements are added. Along with ArrayList you have a complete set of data structures in the Java specs to store the elements, like Maps, Sets, Lists, etc...
When instantiating an ArrayList you should specify which class or interface will describe the objects you are storing within the data structure, so you'll have to use generics to instantiate the structure. In your case:
ArrayList<String> dim1=new ArrayList<String>();
ArrayList<ArrayList<String>> dim2=new ArrayList<ArrayList<String>>();
ArrayList<ArrayList<ArrayList<String>>> dim3= new ArrayList<ArrayList<ArrayList<String>>>();
As you can see this structure is way sexier than the simple arrays above, but obviusly will require more care to deal with it. Don't forget to instantiate your arraylists before putting them in your 3d matrix, or you'll get an exception later for accesing a null objects.
try this..
Map<Integer, HashMap<String, HashMap<String, Integer>>> map = new HashMap<>();
HashMap<String, Integer> hm = new HashMap<>();
hm.put("Velocity", 1);
hm.put("acceleration", 2);
HashMap<String, HashMap<String, Integer>> state1 = new HashMap<>();
state1.put("state1", hm);
map.put(1, state1);
System.out.println(map);

Optimal way of pairing up string values java

I want some way to pair String values and pass it on as a data structure. Any recommendations? Would a Map work? The issue that I'm having with a Map is that not all strings will be paired in this context, only a few of them. I need to have all the strings and if there exists one, it's string pair as well. If anything lacks clarity, let me know.
A Map can be used, with a special value for string without pair.
Well, this is probably not the best way, but what I sometimes use is a duplex type structure that is similar to Python's tuple.
I build a generic structure like so:
class Duplex<T,T> {
private T item1, item2;
public Duplex(T one){
item1 = one;
}
public Duplex(T one, T two){
item1 = one;
item2 = two;
}
//Getters + Accessors
}
Doesn't have to be generic, but it lets you reuse it for other situations.
I haven't used maps before though, so those might actually be better.
A map will give you the key value pairing that you want. What you may want is something like this:
class MyPair
{
String first;
String second;
// Equals and Hashcode
}
Now it is up to you to decide the inner parameters of your MyPair class.
Map pairings = new HashMap();
Since most of your elements will be one String I suggest turning your pairs into Strings as well.
public static final String SEP = "\uFFFF"; // not a valid character by definition.
public static String pair(String a, String b) {
return a + SEP + b;
}
public static String[] split(String str) {
return str.split(SEP);
}
One straightforward way is to use arrays.
List<String[]> pairs = new ArrayList<String[]>();
...
pairs.add(new String[]{"first", "second"});
pairs.add(new String[]{"pairless"});
Or use whatever container you want, List here is just an example, point is String[].
Note: Using plain array is sort of "quick and dirty", it's more "proper" to create a custom "Pair" class. Especially if you have methods which operate on sigle pair, it makes sense to create a class to contain them. In that class you can still internally use this kind of array to store 1 or 2 (or some other number of) items.

Map[] myArr, each with <K>Integer, <V>HashSet ... can't get to HashSet (Java)

I'm not able to navigate down to the HashSets in my datastructure
I declared an array of Map[] and populated it with HashMap with K of Integer, and V of HashSet of String but was unable to add items to the HashSet.
I've trimmed the code down to illustrate ...
private Map[] myMaps = null;
myMaps = new Map[numRepeats];
myMaps[0] = new HashMap<Integer,HashSet<String>>();
myMaps[0].put(0, new HashSet<String>());
The popup in NetBeans shows I can get to java.util.Map with
myMaps[0].
but using the map.get(0) method I thought would return the HashSet
myMaps[0].get(0).
shows I've got to generic java.lang.object, not to the HashSet. Since I need to use the HashSet.add() method next this means I'm stuck. I would appreciate suggestions.
Thank you
You need to cast it to HashMap<Integer,HashSet<String>>.
When you define your map, you could define it with the full types involved, so:
private Map<Integer, HashSet<String>>[] myMaps = null;
Then, you wouldn't have to cast it back (assuming all your maps in myMaps will be of that type).
Unfortunately, Java Generics make it rather tricky to have an array of a generic class. However, it is possible, and it will solve your problem in a typesafe way.
1st. declare your map like this
private Map<Integer,Set<String>>[] myMaps = null;
2nd. use a utility function to allocate
#SuppressWarnings("unchecked")
public static <T> T[] newMapArray( int size )
{
return (T[])java.lang.reflect.Array.newInstance(Map.class, size);
}
3rd. allocate myMaps like this
myMaps = newMapArray(numRepeats);

Categories