I have this code:
_leftArray[0] = _square[6][4];
_leftArray[1] = _square[8][4];
_leftArray[2] = _square[9][5];
I want to be able to extract the values of the array. I'd like to write a method that takes the array position as an argument and returns the coordinates. So if the method was called returnCoordinatesFromArray, I could type returnCoordinatesFromArray[1] and return 6 as a variable and 4 as a variable, so I could use them in another method.
If these are static, hard-coded values, why not do something like this:
Map<Integer, int[]> indexToCoordinateMap = new LinkedHashMap<Integer, int[]>();
indexToCoordinateMap.put(0, new int[]{6, 4});
indexToCoordinateMap.put(1, new int[]{8, 4});
indexToCoordinateMap.put(2, new int[]{9, 5});
Then you don't need the method. You can simply get an array of values where the 0th index is the x coordinate and the 1st index is the y coordinate. Of course, this is by convention. If you want to be more specific, you can use Point and do something like this:
Map<Integer, Point> indexToPointMap = new LinkedHashMap<Integer, Point>();
indexToPointMap.put(0, new new Point(6, 4));
indexToPointMap.put(1, new Point(8, 4));
indexToPointMap.put(2, new Point(9, 5));
Then you can simply do:
Point point = indexToPointMap.get(0);
Do a double for loop and save the x and y positions.
_square value;
int posX=0;
int posY=0;
for(int i=0; i<arr.length; i++) {
for(int j=0; j<arr.length; j++) {
if(arr[i][j]==value) {
posX=i;
posY=j;
}
}
}
"I could type returnCoordinatesFromArray[1] and return 6 as a variable and 4 as a variable"
By design it is not possible in Java to return two values at once. If you need to do something like this you could either build your own little Object that holds two variables:
public class Tupel{
private int firstIndex;
private int lastIndex;
public Tupel(int firstIndex, int lastIndex){
this.firstIndex=firstIndex;
this.lastIndex=lastIndex;
}
public int getFirstIndex(){
return this.firstIndex;
}
// the same for lastIndex
}
Then you you store your Tupels in an array Tupel[] leftArray where for example
leftArray[1] = new Tupel(6,4);
Or you use existing classes like Point if they fit your needs.
Related
I am trying to create an array of objects with a MAX_N 6 object into this array, then create another array within an else statement to fit the rest of the array objects.
I would like to name the new array
sbag1
sbag2
etc
here is my code:
public static ShoppingBag[] packIntoBags(GroceryItem[] goods) {
ShoppingBag newBag = new ShoppingBag();
GroceryItem tmpObject = null;
int index = 0;
String bag = "newBag";
String bagNum = bag + index;
for (int i = 0; i < MAXNBAG; i++)
if (newBag.numItems() < MAX_NUM_ITEMS) {
for (int k = 0; i < MAX_NUM_ITEMS; i++) {
tmpObject = goods[i];
newBag.addToBag(tmpObject);
}
}
else {
ShoppingBag newBag1 = new ShoppingBag();
}
}
You will not be able to dynamically create new variables in java.
When I look at the signature of your method you don't need to return multiple variables, only an array of ShoppingBags.
You should create a variable of type List<ShoppingBag>:
List<ShoppingBag> shoppingsBags=new ArrayList<>();
each time you need a new ShoppingBag:
bag=new ShoppingBag();
shoppingBags.add(bag);
at the end convert this list to an array:
return shoppingBags.toArray(new ShoppingBag[0]);
Java is a statically compiled language. In general, it is not possible, or to be precise: not helpful to use "dynamic" names for variables.
What you could do instead: use a Map, or even more simple: an array of arrays to hold your data.
Situation
Well, this method is managing a conversion which accepts a list as a parameter, but definately doesn't look scalable.
List<Long> array_list_data= new ArrayList<>();
public void get_Data() {
long0 = array_list_data.get(0);
long1= array_list_data.get(1);
long2= array_list_data.get(2);
}
Afterwards, it will create a different class with the long fields.
Problem
However, what if we have to expand this data to a 100 parameters on this list?
What I have done so far is:
List<Long> array_list_data= new ArrayList<>();
public void get_Data() {
int k = 0;
long0= array_list_data.get(k);
long1= array_list_data.get(k++);
long2= array_list_data.get(k++);
}
Why incrementing k is not the right way to do it?
k++ performs a post-increment. In other words, the value of the expression is the original value of k, and then k is incremented. It's still incremented before the method is called, but the value passed as the argument is the value before the increment takes place. In other words, a call of:
x = list.get(k++);
is equivalent to:
int tmp = k;
k = k + 1;
x = list.get(tmp);
So if you actually had:
memory_version = array_list_data.get(k++); // Calls with 0, then k=1
mains_voltage_min = array_list_data.get(k++); // Calls with 1, then k=2
mains_voltage_max = array_list_data.get(k++); // Calls with 2, then k=3
then it would be fine, and equivalent to your first code. Your current problem is that you've actually got:
memory_version = array_list_data.get(k); // Calls with 0, then k=0
mains_voltage_min = array_list_data.get(k++); // Calls with 0, then k=1
mains_voltage_max = array_list_data.get(k++); // Calls with 1, then k=2
However, I'd suggest that if you're modelling the data in a class using a collection as a field, you may well be better off with a separate field for each value. (You may create an instance of the class by extracting the data from a list, of course, but that's a different matter.)
k++ will return the value of k then increment it.
++k will increment k then return the incremented value.
You should use ++k in your situation.
It works fine, just k++ does first return k and then increment it by one, so you get k, k, k+1, k+2, etc. Use ++k instead. Or use k++ in the first call, too, your choice.
Although your approach works fine with some tweaking of ++ position, with 100 fields you may be better off with reflection. Put field names into an array or a list, then go through them one by one in a loop, and set values based on a loop variable:
String[] fieldNames = new String[] {"memory_version", " mains_voltage_min", ...};
...
Class<MyClass> c = MyClass.class;
for (int i = 0 ; i != fieldNames.length ; i++) {
Field f = c.getDeclaredField(fieldNames[i]);
f.setLong(this, array_list_data.get(i));
}
This reduces your list processing code to a few simple lines, and lets you change the order of fields in array_list_data simply by arranging your fieldNames array in proper order.
You don't need to maintain the index variable at all; this is why we have iterators:
final Iterator<Integer> iterator = array_list_data.iterator();
memory_version = iterator.next();
mains_voltage_min = iterator.next();
mains_voltage_max = iterator.next();
To manage scalability, I'd use an enum and a Map:
enum Var {
MEMORY_VERSION(0),
MAINS_VOLTAGE_MIN(1),
MAINS_VOLTAGE_MAX(2);
private Integer value;
Var(Integer value) {
this.value = value;
}
public Integer value() { return value; }
}
List<Long> array_list_data= new ArrayList<>();
Map<Integer, Long> variables = new HashMap<>();
public void getData() {
for (int j=0; j<array_list_data.size(); j++) {
variables.put(j, array_list_data.get(j));
}
}
public void test() {
System.out.println("Memory version: " + variables.get(Var.MEMORY_VERSION.value()));
}
so that you can add as many vars as you need, and you can retrieve with a meaningful name, like in the test() method.
Just about the incrementing part, try this:
public void getData() {
int i = 0;
// get element 0, then increment i
memory_version = array_list_data.get(i++);
// get element 1, then increment i
mains_voltage_min = array_list_data.get(i++);
// get element 2, then increment i
mains_voltage_max = array_list_data.get(i++);
}
That's how I do it for example when working with JDBC ResultSet.
I was wondering if you could help me with this problem, I'm stuck for a day in trying to solve this one. So basically what I want to do is have a list that will contain an array of an array.
I have this initialization
List<double[][]> points = new ArrayList<double[][]>();
I add the elements this way:
points.add(existing.Foods);
My beeColony class contains the data that I want to add:
public class beeColony{
double Foods[][]=new double[FoodNumber][D];
....
}
And here's how I declare an instance of it:
public beeColony existing=new beeColony();
Here's a snippet of the code:
for(run=0;run<existing.runtime;run++)
{
for (iter=0;iter<existing.maxCycle;iter++)
points.add(existing.Foods);
}
What happens is that when I output all the items the list, it only contains the last added items.
for example:
Foods = {(0,0), (1,1), (2,2), (3,3)}
points.add(Foods);
Foods = {(4,4), (5,5), (6,6), (7,7)}
points.add(Foods);
The way that I understand it is that
points.get(0)[0] should countain 0,0 and so on and points.get(1)[0] should contain 4,4 and so on. But what happens is points.get(0) also has the same values as points.get(1)
Collections like ArrayList<X> contain references to X objects, like one end of a string the other end of which is "tied" to the object itself, i.e., where the data resides.
This is also true for arrays like double[][].
What you do is to copy and store the reference end repeatedly, but at the other end there is one and the same double[][]. You can change the contents of that array, but all stored string ends lead to the same array object.
You must create new copies of that array to hold different array values. If you create another BeeColony, it will have another foods array. Otherwise, use new double[m][n] and copy the values. This is how:
double[][] d = { {1,2}, {3,4}, {5,6} };
// create the vector of (still missing) rows:
double[][] copy = new double[d.length][];
for( int row = 0; row < d.length; ++row ){
// create another row of appropriate length:
copy[row] = new double[d[row].length];
// copy the element values
System.arraycopy( d[row], 0, copy[row], 0, d[row].length );
}
PS: You should stick to Java conventions. Classe names are written in camel case starting with an upper case letter; variables and methods should start with a lower case letter. Loops should declare the loop counter inside the for: for( int run = 0;... ). Avoid public for class fields; code getters and setters to access private class fields.
You could use combination of array and iterator to get the work done,
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
public class listerr {
static int getrandom(){
Random r = new Random();
int next = r.nextInt(100);
return next;
}
static double[][] getarr(){
double[][] arr = {{getrandom(),getrandom()}, {getrandom(),getrandom()},
{getrandom(),getrandom()}, {getrandom(),getrandom()}};
return arr;
}
public static void main(String[] args) {
List<double[][]> points = new ArrayList<double[][]>();
for(int run=0;run<3;run++)
{
double[][] arr = getarr();
points.add(arr);
}
Iterator itr = points.iterator();
while(itr.hasNext()){
double[][] dbl = (double[][]) itr.next();
for (int i=0;i<4;i++)
{ for (int j=0;j<2;j++){
System.out.println(dbl[i][j]);
}
}
}
}
}
This question is a bit more complex that the title states.
What I am trying to do is store a map of {Object:Item} for a game where the Object represents a cupboard and the Item represents the content of the cupboard (i.e the item inside).
Essentially what I need to do is update the values of the items in a clockwise (positive) rotation; though I do NOT want to modify the list in any way after it is created, only shift the positions of the values + 1.
I am currently doing almost all That I need, however, there are more Object's than Item's so I use null types to represent empty cupboards. However, when I run my code, the map is being modified (likely as it's in the for loop) and in turn, elements are being overwritten incorrectly which after A while may leave me with a list full of nulls (and empty cupboards)
What I have so far...
private static Map<Integer, Integer> cupboardItems = new HashMap<Integer, Integer>();
private static Map<Integer, Integer> rewardPrices = new HashMap<Integer, Integer>();
private static final int[] objects = { 10783, 10785, 10787, 10789, 10791, 10793, 10795, 10797 };
private static final int[] rewards = { 6893, 6894, 6895, 6896, 6897 };
static {
int reward = rewards[0];
for (int i = 0; i < objects.length; i++) {
if (reward > rewards[rewards.length - 1])
cupboardItems.put(objects[i], null);
else
cupboardItems.put(objects[i], reward);
reward++;
}
}
// updates the items in the cupboards in clockwise rotation.
for (int i = 0; i < cupboardItems.size(); i++) {
if (objects[i] == objects[objects.length - 2])
cupboardItems.put(objects[i], cupboardItems.get(objects[0]));
else if (objects[i] == objects[objects.length - 1])
cupboardItems.put(objects[i], cupboardItems.get(objects[1]));
else
cupboardItems.put(objects[i], cupboardItems.get(objects[i + 2]));
}
So how may I modify my code to update so i get the following results..
======
k1:v1
k2:v2
k3:v3
k4:none
=======
k1:none
k2:v1
k3:v2
k4:v3
?
HashMap doesn't guarantee ordering, therefore if you need ordering, use ArrayList or LinkedList.
If you want to stick with HashMap, you need to sort the HashMap based on the key before each rotation. You can sort easily since the keys are Integer objects. But this will affect the performace.
Ragavan has a good answer if you want to stick to your approach. However, you are doing a lot of work to just rotate the items. It would be much more efficient to just rotate the index (using modulus) and keep the arrays the same:
final static List<Integer> objects = new ArrayList<Integer>(
Arrays.asList(10783, 10785, 10787, 10789, 10791, 10793, 10795, 10797));
final static List<Integer> rewards = new ArrayList<Integer>(
Arrays.asList(6893, 6894, 6895, 6896, 6897, -1, -1, -1));
public static int getReward(int obj, int rot){
int rotIndex = (objects.indexOf(obj) - rot)%objects.size();
//modulus in java can be negative
rotIndex = rotIndex < 0 ? rotIndex+objects.size():rotIndex;
return rewards.get(rotIndex);
}
public static void main(String... args){
//This should give 6897, which is the reward for obj 10783 after 4 rotations
System.out.println(getReward(10783,4));
}
How do I store a set of paired numbers in java? Do I use lists or arrays or maybe something else?
eg. [ (1,1) , (2,1) , (3,5)]
There are a few options:
Write a custom IntPair class
class IntPair {
// Ideally, name the class after whatever you're actually using
// the int pairs *for.*
final int x;
final int y;
IntPair(int x, int y) {this.x=x;this.y=y;}
// depending on your use case, equals? hashCode? More methods?
}
and then create an IntPair[] or a List<IntPair>.
Alternately, create a two-dimensional array new int[n][2], and treat the rows as pairs.
Java doesn't have a built-in Pair class for a few reasons, but the most noticeable is that it's easy enough to write a class that has the same function, but has much more enlightening, helpful names for the class, its fields, and its methods.
If we knew more about what you're actually using this for, we might be able to provide more detailed suggestions -- for all we know, a Map could be appropriate here.
If you're using JavaFX, you can use the class Pair.
import javafx.util.Pair;
int x = 23;
int y = 98;
Pair<Integer, Integer> pair1 = new Pair<>(6, 7);
Pair <Integer, Integer> pair2 = new Pair<>(x, y);
Way 1 : Using javafx.util.Pair class
Pair<Integer> myPair1 = new Pair<Integer>(10,20);
Pair<Integer> myPair2 = new Pair<Integer>(30,40);
HashSet<Pair<Integer>> set = new HashSet<>(); // Java 8 and above
set.add(myPair1);
set.add(myPair2);
Way 2: Using int[] of size 2
int[] myPair1 = new int[] {10,20}; // myPair1[0]=10 , myPair[1] = 20
int[] myPair2 = new int[] {30,40};
HashSet<int[]> set = new HashSet<>(); // Java 8 and above
Way 3 : Converting pair into single number
int myPair1 = 10 * 1000 + 20;
// int first = myPair1 / 1000; second = myPair2 % 1000;
int myPair2 = 30 * 1000 + 40;
HashSet<Integer> set = new HashSet<>();
set.add(myPair1);
set.add(myPair2);
Way 4 : Using ArrayList instead of int[] in way 2
Way 5 : Custom class that uses HashSet and Pair internally
class Pair<T> {
T p1, p2;
Pair(T p1, T p2) {
this.p1 = p1;
this.p2 = p2;
}
Pair<Integer> pair = new Pair<Integer>(1,2);
int i1 = pair.p1;
int i2 = pair.p2;
You can also put in getters, setters, equals, hashcode, etc.
If you can live with low level structures and desperately need compact form of "literal" form of "set of pairs" -- this happens to me in unit test, when I need a set of fixtures -- you can simply use an array of arrays:
int[][] squares = {
{ 1, 1 },
{ 2, 4 },
{ 3, 9 }
};
But keep in mind that there is no semantic to such a type -- it all depends on proper use, compiler won't give you a warning if you type squares[0][1] when you really wanted squares[1][0].
If you're needing to avoid duplicates then a HashSet would be a good choice but it not then an ArrayList would work.
Class IntPair(){
int i;
int j;
}
HashSet<IntPair> set = new HashSet<IntPair>();
or
ArrayList<IntPair> list = new ArrayList<IntPair>();