This code generates unsorted array. My question is how do I clone the generated array so I can reuse the unsorted array in different sorting algorithms.
public class UnsortedData{
private int [] coreData;
private int maxArraySize;
private int currentArraySize;
public UnsortedData(int size){
this.maxArraySize = size;
this.coreData = new int[this.maxArraySize];
this.currentArraySize = 0;
}
public boolean addData(int data){
if (currentArraySize < maxArraySize)
{
coreData[currentArraySize] = data;
currentArraySize++;
return true;
}
return false;
}
public class dataSorting {
public static void main(String[] args) {
Random rand = new Random();
UnsortedData uD = new UnsortedData(1000000);
for (int x = 0; x < 50; x++) {
uD.addData(rand.nextInt(3000000));
}
}
Use build in methods from java.lang.Object to clone the original array and java.util.Arrays to sort the cloned array.
int[] arr = {6,9,4,5}; // original array
int[] arrCopy = arr.clone() // we created a copy of the array
Arrays.sort(arrCopy); // it sort the array that we cloned
References: Arrays Class , Class Object
Easiest way? Object.clone()
int[] arr = coreData.clone();
You can also use the Stream API or external libraries such as Apache Commons.
Related
I have a class called CanvasState which holds two 2D arrays, and a static ArrayList.
public class CanvasState {
private int [][] colorArray;
private boolean [][] boolArray;
private static List<CanvasState> listState = new ArrayList<>();
public CanvasState(int [][] colorArray, boolean [][] boolArray){
this.colorArray = colorArray;
this.boolArray = boolArray;
}
public void addToArrayList(CanvasState canvasState){
listState.add(canvasState);
}
}
So whenever the canvas is drawn on and the user lifts their finger I save the state.(This is in another Class)
if(event.getAction() == MotionEvent.ACTION_UP){
canvasState = new CanvasState(colors, cellChecked);
canvasState.addToArrayList(canvasState);
}
I was expecting to get an ArrayList of CanvasStates holding my 2D arrays with their adjusted values, but it seems that while a new CanvasState object is being created on every ACTION_UP every CanvasObject is getting re-written so both arrays are the same for all objects in the ArrayList. Is there any way around this? OR is ArrayList not suitable for this?
The problem is that your CanvasState objects all reference the same 2D arrays (colorArray and boolArray).
You need to copy the current state of these arrays in your constructor.
public CanvasState(int [][] colorArray, boolean [][] boolArray){
this.colorArray = copy2D(colorArray);
this.boolArray = copy2D(boolArray);
}
Using these utility methods (or some other method of your choice for cloning 2D arrays):
static int[][] copy2D(int[][] arr)
{
int[][] narr = new int[arr.length][];
for(int i=0; i<arr.length; i++)
narr[i] = arr[i].clone();
return narr;
}
static boolean[][] copy2D(boolean[][] arr)
{
boolean[][] narr = new boolean[arr.length][];
for(int i=0; i<arr.length; i++)
narr[i] = arr[i].clone();
return narr;
}
I have a class Ttp which has a ArrayList<City>loaded from file. In constructor of Ttp I randomly shuffle a list read from file and assign it to the object.
public class Ttp {
private ArrayList<City> cities;
public Ttp() {
cities = Utils.shuffleArray(Loader.getCities());
}
}
This way I get 10 objects with nicely shuffled arrays:
public static void main(String args[]) {
Loader.readFile("easy_0.ttp");
for(int i=0; i<10; i++){
System.out.println(new Ttp());
}
}
But in this scenario, when I try to create ArrayList<Ttp> I get a collection full of the same objects (instances of Ttp with the same arrays of cities)
public static void main(String args[]) {
Loader.readFile("easy_0.ttp");
ArrayList<Ttp> arrayList = new ArrayList<>();
for(int i=0; i<10; i++){
arrayList.add(new Ttp());
}
arrayList.forEach(System.out::println);
}
Shuffle function:
public static <T> ArrayList<T> shuffleArray(ArrayList<T> arrayList) {
if (arrayList != null && arrayList.size() > 0) {
int numberOfRolls = Random.getGenerator().nextInt((arrayList.size() - arrayList.size() / 3) + 1) + arrayList.size() / 3;
int indexA;
int indexB;
T objectA;
for (int i = 0; i < numberOfRolls; i++) {
indexA = Random.getGenerator().nextInt(arrayList.size());
indexB = Random.getGenerator().nextInt(arrayList.size());
objectA = arrayList.get(indexA);
arrayList.set(indexA, arrayList.get(indexB));
arrayList.set(indexB, objectA);
}
}
return arrayList;
}
To pick random indexes in shuffle function I am using java.util.Random:
public class Random {
private static final java.util.Random generator = new java.util.Random();
public static java.util.Random getGenerator() {
return generator;
}
}
If Loader.getCities() returns the same list every time that means shuffleArray() is shuffling the same list over and over and every Ttp.cities has a reference to the same unitary list.
The fix is to make a copy somewhere. It could be in getCities(), it could be in shuffleArray(), or it could be in the Ttp constructor:
cities = Utils.shuffleArray(new ArrayList<>(Loader.getCities()));
I am trying to sum N pairs of ints--an Nx2 ArrayList--and return the N summations as an ArrayList. While I understand it is not necessary to set up a class to accomplish this, I would like to do so as practice for future projects.
import java.util.ArrayList;
public class SumsInLoop {
public SumsInLoop(int numberOfPairs, ArrayList<ArrayList<Integer>> numbersList) {}
public ArrayList<Integer> getSums(int numberOfPairs, ArrayList<ArrayList<Integer>> numbersList) {
ArrayList<Integer> pairsOfSums = new ArrayList<Integer>();
for (ArrayList<Integer> Pair : numbersList) {
int x = Pair.get(0);
int y = Pair.get(1);
int sum = x + y;
pairsOfSums.add(sum);
}
System.out.println(pairsOfSums);
return pairsOfSums;
}
The data that I am given is a random assortment of N pairs (numbersOfPairs) of integers, e.g. 612673 108695. I would like to add these pairs of integers to a 2D ArrayList (numbersList) that will be called by getSums.
However, I am having difficulties initializing numbersList. My main function is as follows:
public static void main(String[] args) {
int myNumberOfPairs = 13;
ArrayList[][] myNumbersList = new ArrayList[13][2];
myNumbersList[0][0] = new ArrayList<>();
myNumbersList[0][0].add(612673);
myNumbersList[0][1].add(108695);
myNumbersList[1][0] = new ArrayList<>();
myNumbersList[1][0].add(756875);
myNumbersList[1][1].add(496058);
SumsInLoop mySum = new SumsInLoop(myNumberOfPairs,myNumbersList);
mySum.getSums(myNumberOfPairs, myNumbersList);
The last two lines of code throw errors, asking me to change myNumbersList to type ArrayList<List<Integer>> which throws even more errors, even after changing all 2D ArrayLists to type ArrayList<List<Integer>>.
So, my two questions are as follows:
How can I initialize an NxM ArrayList and populate it correctly?
Is there a faster way of accomplishing this task while still using a class method?
P.S. I'm used to coding in Python and am self-teaching myself Java, so any other information or resources you can provide me with are much appreciated.
You may want to simplify your input by using 2D array of int : int[][] myNumbersList = new int[13][2];
The expected output in that case is a 1D array of int[13] that can be obtained as follows (demonstrated with 2 pairs. See mcve ) :
public class SumsInLoop {
//pairsOfInts should be an [n][2] array
private static int[] sumOfPairs(int[][] pairsOfInts) {
int[] sums = new int[pairsOfInts.length];
for(int pairIndex = 0; pairIndex < pairsOfInts.length; pairIndex++) {
sums[pairIndex]= pairsOfInts[pairIndex][0]+pairsOfInts[pairIndex][1];
}
return sums;
}
public static void main(String[] args) {
int numberOfPairs = 2;
int[][] pairsOfInts = new int[numberOfPairs][2];
pairsOfInts[0] = new int[] {612673,108695 };
pairsOfInts[1] = new int[] {756875,496058 };
int[] sumOfPairs = sumOfPairs(pairsOfInts);
System.out.println(Arrays.toString(sumOfPairs));
}
}
If you want a solution implemented with List you can make use of javafx Pair (or make your own pair class.
The input can be defined as List<Pair<Integer,Integer>> pairsOfInts = new ArrayList<>();
The out put can be an array as above, or a List<Integer>:
import java.util.ArrayList;
import java.util.List;
import javafx.util.Pair;
public class SumsInLoop {
private static List<Integer> sumOfPairs(List<Pair<Integer, Integer>> pairsOfInts) {
List<Integer> sums = new ArrayList<>();
for(Pair<Integer,Integer> pair : pairsOfInts) {
sums.add(pair.getKey()+ pair.getValue());
}
return sums;
}
public static void main(String[] args) {
List<Pair<Integer,Integer>> pairsOfInts = new ArrayList<>();
pairsOfInts.add (new Pair<>(612673,108695 ));
pairsOfInts.add (new Pair<>(756875,496058));
List<Integer> sumOfPairs = sumOfPairs(pairsOfInts);
System.out.println(sumOfPairs);
}
}
The (compile) exception you are getting is due to the fact that you expect a ArrayList<ArrayList<Integer>>, but pass an ArrayList[][]. (which is not the same in Java)
In your case you'd need (in the main method):
ArrayList<ArrayList<Integer>> myNumbersList = new ArrayList</* when java > 6 ;)*/>(13);
this only sets the capacity of the (parent) list (..and the underlying/internal backing array)
to initialize the child lists, you'd not come around looping (somehow...even not in python :):
for (int i = 0; i < 13; i++) {
myNumbersList.add(new ArrayList<Integer>(2));
}
Depends on what means "correctly" ...but I assume with "random data", ideally you would again inner loop:
java.util.Random rnd = new Random(/*seed default current timestamp*/);
//...
for (int i = 0; i < 13; i++) {
ArrayList<Integer> innerList = new ArrayList<>(2);
for (int j = 0; j < 2; j++) {
innerList.add(rnd.netxInt(/*bound default Integer.MAX_VALUE*/) /*+/-/% offset*/);
}
myNumberList.add(innerList);
}
Sorry I am not aware of one (faster way), but much depends on the "input format".
Since you already know the amount of values in a pair, an ArrayList is unnecessary. You can create your own, simpler implementation of a pair.
class Pair {
public final int left;
public final int right;
public Pair(int left, int right){
this.left = left;
this.right = right;
}
}
You can then access the values by creating a pair object and accessing its fields.
Pair p = new Pair(10, 7);
System.out.println(p.left); // 10
System.out.println(p.right); // 7
You can then more easily redefine your getSums method.
public static List<Integer> getSums(List<Pair> pairs){
List<Integer> pairsOfSums = new ArrayList<>();
for(Pair pair : pairs){
int sum = pair.left + pair.right;
pairsOfSums.add(sum);
}
return pairsOfSums;
}
Please also notice the function can be static and you don't need to pass the number of pairs. The for-each loop will cycle through all of them regardless.
Initializing the array is then easier than the method you have described in the question.
List<Pair> pairs = new ArrayList<>();
pairs.add(new Pair(7, 10));
pairs.add(new Pair(18, 3));
pairs.add(new Pair(-6, 0));
pairs.add(new Pair(4, 2));
System.out.println(SumsInLoop.getSums(pairs));
I am trying to clone an array and return as an object, not an array type.
z
public IntVector clone()
{
IntVector cloneVector = new IntVector(3);
int[] newItems = new int[10];
for(int i=0 ; i<itemCount_; ++i)
{
newItems[i] = items_[i];
}
cloneVector = newItems; // is there a way to do something like this??
return cloneVector;
}
Main method looks like this
public static void main(String[] args)
{
IntVector vector = new IntVector(5);
vector.push(8);
vector.push(200);
vector.push(3);
vector.push(41);
IntVector cloneVector = vector.clone();
}
*there are two other methods which makes an array:IntVector() and puts value into array:push()
Declare a new constructor for IntVector which takes an int array and a count:
IntVector(int[] data, int n) {
items_ = data.clone();
itemCount_ = n;
}
Then you can write clone like this:
public IntVector clone() {
return new IntVector(items_, itemCount_);
}
You can make that new constructor private if you like, so only clone can use it.
I want a function / data structure that can do this:
func(int dim){
if(dim == 1)
int[] array;
else if (dim == 2)
int[][] array;
else if (dim == 3)
int[][][] array;
..
..
.
}
anyone know how?
Edit
Or you could use Array.newInstance(int.class, sizes). Where sizes is an int[] containing the desired sizes. It will work better because you could actually cast the result to an int[][][]...
Original Answer
You could use the fact that both int[] and Object[] are Objects. Given that you want a rectangular multidimensional array with sizes given by the list sizes
Object createIntArray(List<Integer> sizes) {
if(sizes.size() == 1) {
return new int[sizes.get(0)];
} else {
Object[] objArray = new Object[sizes.get(0)];
for(int i = 0; i < objArray.length; i++) {
objArray[i] = createIntArray(sizes.subList(1, sizes.size());
}
return objArray;
}
}
You lose all static type checking, but that will happen whenever you want a dynamically dimensioned array.
If your purpose is to create a truly dynamic array, then you should look at the Array object in the JDK. You can use that to dynamically generate an array of any dimension. Here is an example:
public void func(int dim) {
Object array = Array.newInstance(int.class, new int[dim]);
// do something with the array
}
Once the array Object has been created, you can use the methods of the java.lang.reflect.Array class to access, add, remove elements from the multi-dimension array that was created. In also includes utility methods to determine the length of the array instance.
You can even check the dimension of the array using:
public int getDimension(Object array) {
int dimension = 0;
Class cls = array.getClass();
while (cls.isArray()) {
dimension++;
cls = cls.getComponentType();
}
return dimension;
}
People have post good solutions already, but I thought it'd be cool (and good practice) if you wrap the dynamic multidimensional array into a class, which can use any data structure to represent the multi-dimensional array. I use hash table so you have virtually unlimited size dimensions.
public class MultiDimArray{
private int myDim;
private HashMap myArray;
public MultiDimArray(int dim){
//do param error checking
myDim = dim;
myArray= new HashMap();
}
public Object get(Integer... indexes){
if (indexes.length != myDim){throw new InvalidArgumentException();}
Object obj = myArray;
for (int i = 0; i < myDim; i++){
if(obj == null)
return null;
HashMap asMap = (HashMap)obj;
obj = asMap.get(indexes[i]);
}
return obj;
}
public void set(Object value, Integer... indexes){
if (indexes.length != myDim){throw new InvalidArgumentException();}
HashMap cur = myArray;
for (int i = 0; i < myDim - 1; i++){
HashMap temp = (HashMap)cur.get(indexes[i]);
if (temp == null){
HashMap newDim = new HashMap();
cur.put(indexes[i], newDim);
cur = newDim;
}else{
cur = temp;
}
}
cur.put(indexes[myDim -1], value);
}
}
and you can use the class like this:
Object myObj = new Object();
MultiDimArray array = new MultiDimArray(3);
array.put(myObj, 0, 1, 2);
array.get(0, 1, 2); //returns myObj
array.get(4, 5, 6); //returns null
What about a class like following?
class DynaArray {
private List<List> repository = new ArrayList<List>();
public DynaArray (int dim) {
for (int i = 0; i < dim; i++) {
repository.add(new ArrayList());
}
}
public List get(int i) {
return repository.get(i);
}
public void resize(int i) {
// resizing array code
}
}