Reputation: 2105
So far, in a program that I am writing, I have been using arrays to store data about line segments. For the sake of the question, let's assume these arrays only contain integers that define start (x1, y1) and end (x2, y2) coordinates.
Integer[] lineData = {x1, y1, x2, y2};
In my program, I need to continuously perform operations on the data contained in multiple such arrays using for loops.
In the course of writing the program, I have, numerous times, realized that I need more data about those segments. As a result, I added elements to the array, which grew larger, for instance:
Integer[] lineData = {x1, y1, x2, y2, slope, red, green, blue, width};
This has become hard to manage, since I need to remember the position of each integer data to perform operations on it and it is very tedious to implement changes to the array, such as swapping the position of two elements, since I need to update the index of the elements in every part of the program that performs operations on them.
This has led me to the probably obvious idea to create a lineData class which contains the integers as its fields:
public class LineData {
public int x1,y1,x2,y2,slope, red, green, blue, width;
LineData(int x1, int y1, int x2, int y2, int slope, int red, int green, int blue, int width){
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.slope = slope;
this.red = red;
this.green = green;
this.blue = blue;
this.width = width;
}
public int getX1() {
return x1;
}
public void setX1(int x1) {
this.x1 = x1;
}
public int getY1() {
return y1;
}
public void setY1(int y1) {
this.y1 = y1;
}
public int getX2() {
return x2;
}
public void setX2(int x2) {
this.x2 = x2;
}
public int getY2() {
return y2;
}
public void setY2(int y2) {
this.y2 = y2;
}
public int getSlope() {
return slope;
}
public void setSlope(int slope) {
this.slope = slope;
}
public int getRed() {
return red;
}
public void setRed(int red) {
this.red = red;
}
public int getGreen() {
return green;
}
public void setGreen(int green) {
this.green = green;
}
public int getBlue() {
return blue;
}
public void setBlue(int blue) {
this.blue = blue;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
}
This looks like a good solution.
My concern, though, is that accessing and changing the fields of the lineData class will be slower than accessing and changing the elements in the array. The reason behind my concern is the belief that Arrays exist for a reason.
Another argument for using a lineList class is the need to store data about the line segments that are not integers, but Strings, Booleans and other custom objects.
However, please disregard that argument. I would like to compare an integer array with a class containing solely integer fields.
Summing up, my questions are:
Which one is faster: an array of x integers or an object containing x integer fields? How did you solve the described issue when you faced it in the past? If using an object with fields is slower than using an array, did you still decide to use an object with fields? Why?
Please take into account that there is a very high number of those arrays, so changing the arrays to objects with fields would create a very high number of instantiated objects that are looped over - maybe this has an effect on performance?
Thanks a lot in advance for your help!
Upvotes: 2
Views: 129
Reputation: 32145
Using a LineData
class to store your objetcs is much suitable, readable and surely faster than saving all the data successively in the same Array.
Because in that case for each line details you whould have to iterate the Array twice, first to reach the beginning of each line details and the second to loop throught those details which is very expensive and unwanted.
And for structure performance, using a Java Collections(List, Set and Map) to store those lines is better than using an Array, and to decide which one to use we need to know the difference between them and when to use each one of them:
And I think in your case you just need to use a List of LineData objects (List<LineData>
) to get a faster access to its elements:
Upvotes: 1
Reputation: 6033
First, I would say that if you handle only integers and you strive for performances, then you should certainly use int[]
instead of Integer[]
:
int[]
is one single object that contains an array of native integers (4 bytes)Integer[]
is an array of Integer
class, which means as many objects as the length of the array when all are instantiated.Now on your question.
Frankly, on your design and independently of performance issues, you should go for the LineData
class. I don't see any good reason to implement a pseudo object in an array. Conceptually, it does not make sense to store things of different nature like slope
, color
, x
, y
,... in the same array. An array (even native) is a kind of collection, and then should contain values that are of the same nature.
On the performance, I would say the compiler can easily optimise getter and setter on an object.
Upvotes: 2
Reputation: 476537
Array
s exist to store a number of instance where the number is unknown, or where you will have to iterate over the instance and perform the same operation on them.
As a result it is better that an array contains the same (semantical) type of objects. This was in this case not true, you store a line width after a coordinate. Although technically there is no problem, it will be hard to maintain.
So from a development point of view, it is better to create a class that stores segments, and then store different line segments in an array.
So what you probably need is a LineData[]
array. Where in each element you store the data of one line.
From a performance point of view, there is not much difference.
null
check on the object.null
-check on the array and an index
check (this index check can be done in one operation if optimized (and on a machine with a reasonable instruction set).However if you are not sure on the number of line segments in advance, you better use an List<LineData>
instance, thus a LinkedList
or an ArrayList
.
Upvotes: 1
Reputation: 2647
Did you considered to use something like a list or a set?
List<Interger> myList = new ArrayList<Integer>();
myList.add(5);
boolean foo = myList.contains(5); // true
foo = myList.contains(6); // false
int size = myList.size(); // 1
foo = myList.isEMpty(); //false
myList.remove(new Integer(5));
size.size() // 0
foo = myList.isEmpty(); // true
Or maybe what do you need is a Map?
Map myMap<String,Integer> = new HashMap<String, Integer>();
myMap.put("blue", 5);
myMap.put("red", 6);
int value = myMap.get("red"); // 6
int size = myMap.size(); //2
myMap.remove("red");
size = myMap.sie(); //2
and the list of trick you can do goes on, are you sure you are using the right data structure?
Upvotes: 1