I'm doing a project, where I'm reading accelerometer sensor data from a smartwatch. The app that is made has a start and stop button, that starts and stops the sensor readings, respectively.
I would like to start recording the data when the user presses start - I know how to access the sensor data, but I need a way to store the data until the stop button is pressed. Accelerometer data is X-, Y-, and Z-axis data, that could look something like this:
[2.034343, 8.342423, 0.012313]
So I need a way to store this type of vector within an additional array, in order to separate each vector recorded. Thus, the data structure I'm looking for should look something like this when having recorded three vectors of data:
[[2.034343, 8.342423, 0.012313], [6.031843, 2.349153, 0.012313], [1.734843, 5.342423, 1.012393]]
The data structure will be filled with these vectors in the time between the user pressing start to when stop is pressed.
Do I need an ArrayList of ArrayLists? Or do you have any other suggestions as to what the best data structural solution to this is? As of right now, the data only needs to be stored as long as the app is running.
I have no idea why I cannot figure out how to do this in Kotlin, I have only been able to make an ArrayList of ArrayList, however, instead of separating each vector with the brackets (as shown above) it just appends all the vector values to an array that holds all values (like a standard array).
Hope I can get some help. Thanks in advance.
CodePudding user response:
A data class could make sense:
data class Point(val x: Double, val y: Double, val z: Double)
val list = mutableListOf<Point>()
list.add(Point(2.034343, 8.342423, 0.012313))
list.add(Point(6.031843, 2.349153, 0.012313))
list.add(Point(1.734843, 5.342423, 1.012393))
for (point in list) {
println("Point: " point.x " | " point.y " | " point.z)
}
CodePudding user response:
If you want to do this with a 2D structure, you can instantiate an ArrayList or MutableList, and then you just add lists to it each time you have new data. If you use ArrayList specifically, you can specify the initial size. Setting a large initial size can help avoid the list having to resize itself while you're adding data, which can be an expensive operation if it has become large.
val data = ArrayList<List<Float>>(10000)
//adding data:
data.add(listOf(xData, yData, zData))
However, I would probably use a 1D collection because all the data points are Floats (or Doubles?) and it's easy to read them 3 at a time. Then you aren't having to create a new collection object to wrap each data point, which requires more memory allocation.
Normally, I wouldn't do something like this, which sacrifices code clarity and conciseness, but since you're recording a stream of data that could be very large, it makes sense to optimize it a bit up front.
val data = ArrayList<Float>(30000)
//adding data:
data.add(xData)
data.add(yData)
data.add(zData)
//iterating the data later:
for (i in 0 until data.size step 3) {
val x = data[i]
val y = data[i 1]
val z = data[i 2]
//...
}
// Or if you have a Point class, you could create a wrapper class
// for getting the points lazily:
class PointAccessor(val source: List<Float>) {
operator fun get(index: Int): Point {
val i = index * 3
return Point(source[i], source[i 1], source[i 2])
}
}
val pointData = PointAccessor(data)
val someX = pointData[4].x