ArrayList field not correctly gathered - kotlin

I'm actually new at Kotlin, and I encounter the following problematic:
I have a class holding an ArrayList of EnsembleVerifier class.
This other class is instantiated with an ArrayList of Square.
When I tried to get this ArrayList, I discovered that this one has no element inside.
Is there any absurdity/misconception in my code? Is it something else? Thank you in advance! :)
GridVerifiers.kt
class GridVerifiers(private val grid: Grid) {
private var verifiers: ArrayList<EnsembleVerifier> = ArrayList()
init {
generateVerifiers()
}
private fun generateVerifiers() {
generateLineVerifiers()
generateColumnVerifiers()
generateSubGridVerifiers()
}
private fun generateLineVerifiers() {
val line: ArrayList<Square> = ArrayList()
for (lineIndex in grid.gridState.indices) {
for (columnIndex in grid.gridState.indices)
line.add(grid.gridState[lineIndex][columnIndex])
println(line.size) // returns 9
verifiers.add(EnsembleVerifier(line))
line.clear()
}
}
...
EnsembleVerifier.kt
class EnsembleVerifier(private val squares: ArrayList<Square>) {
...
fun isValid(): Boolean {
val buffer: ArrayList<Int> = ArrayList()
println(squares.size) // returns 0!
for (square in squares) {
if (square.value in buffer) return false
buffer.add(square.value)
}
return true
}

In java most of the time you are working with references to objects. This means in your case, that your are always working with the same array line. Therefore, when you call line.clear you are cleaning the array that that reference is pointing at, and that's causing your issue with empty arrays.
You need to generate new objects every time instead of cleaning the list.
private fun generateLineVerifiers() {
for (lineIndex in grid.gridState.indices) {
val line: ArrayList<Square> = ArrayList()
for (columnIndex in grid.gridState.indices)
line.add(grid.gridState[lineIndex][columnIndex])
println(line.size) // returns 9
verifiers.add(EnsembleVerifier(line))
}
}

Related

Can't call a function from CountDownTimer object. What am I missing?

I'm going through Googles Kotlin Compose tutorials. One of the tasks is to build a game where you unscramble words. After completing it, I tried to improve the game on my own, and just can't figure out how to add a countdown timer to it. I want the program to skip a word when time runs out.
I'm a programming noob, it's not quite clear to me yet how classes and objects work and how they differ from functions.
The code for the timer at the moment:
object Timer: CountDownTimer(60000, 1000) {
override fun onTick(millisUntilFinished: Long) {
TODO("Not yet implemented")
}
override fun onFinish() {
skipWord() // <<----------- **Unresolved reference: skipWord**
}
}
Elsewhere in my code I have:
class GameViewModel : ViewModel() {
//....
fun skipWord() { // <<---------------- Function that skips to the next word
updateGameState(_uiState.value.score)
updateUserGuess("")
}
//.....
private fun pickRandomWordAndShuffle(): String {
// Continue picking up a new random word until you get one that hasn't been used before
if (currentLanguage == "English") {
currentWord = engWords.random()
} else {
currentWord = finWords.random()
}
setPointAmount()
Timer.start() // <<---------------Start a new countdown for a new word.
if (usedWords.contains(currentWord)) {
return pickRandomWordAndShuffle()
} else {
usedWords.add(currentWord)
return shuffleCurrentWord(currentWord)
}
}
}
Also, a separate problem: the .random() always uses the same seed and picks the same words to unscramble.
Change
object Timer: CountDownTimer(60000, 1000) {
...
to
val timer = object: CountDownTimer(60000, 1000) {
...
and put in into your GameViewModel class.
To solve random issue provide some seed to Random object, like:
var myRandom = Random(System.currentTimeMillis())
and then
currentWord = engWords[myRandon.nextInt(engwords.lastIndex)]

How to count the number of objects created in Kotlin?

In the following code snippet i have created 4 instances of CompanionClass and want to know how many
instances i have created , so have tried many ways but didn't work. Here i used companion object class
to keep track of objects but i know it has no connection with objects because keepTrackOfObjects() is
static. Can anyone help me solve this, please?
class CompanionClass
{
companion object{
var numberOfObjects = 0
fun keepTrackOfObjects() = println("number of created objects currently is: +
${++numberOfObjects}")
}
}
fun main()
{
val obj1 = CompanionClass()
CompanionClass.keepTrackOfObjects()
val obj2 = CompanionClass()`enter code here`
val obj3 = CompanionClass()
val obj4 = CompanionClass()
CompanionClass.keepTrackOfObjects()
}
// output is
// 1
// 2
You can use the init block to count the elements you created:
class CompanionClass {
companion object {
var counter: Int = 0
fun counter(): Int {
return counter
}
}
init {
counter++
}
}
You can test the behavior in this kotlin playground.
The problem is with your companion Object,
var numberOfObjects = 0
will initialise the variable every time you create a new instance. So create this variable in a separate class where keep all static content and use it from there. then you companion object will be like this.
companion object{
fun keepTrackOfObjects() = println("number of created objects currently is: +
${++numberOfObjects}")
}
To achieve this, you should increment your numberOfObject in a init statement.. Get a look at the code below
class User (var firstName:String,var lastName:String){
companion object {
var numberofinstance:Int = 0
fun getNumberOfInstance() = println("Nombre d'instance = $numberofinstance")
}
init {numberofinstance++}
}
Now you can use it in your main function
fun main(){
val user1=User("bob","marley")
val user2=User("bonkey","reynard")
val user3=User("jobbs","steve")
val user4=User("bill","naim")
val user5=User("jeff","romain")
User.getNumberOfInstance()
}
Output : Number of instance = 5

My non-nullable ArrayList is returning a null upon calling it and throwing a Null Pointer Exception

Running this on IntelliJ IDEA 2020.11 using JDK 14 and coding it in Kotlin.
I have a class with a variable menuComponents which is an ArrayList full of MenuComponents, but it's empty at initialization.
var menuComponents: ArrayList<MenuComponent> = ArrayList()
I want to edit the components so I wrote this.
for (component in menuComponents) {
//Do some stuff. The stuff doesn't matter, it throws an exception if I leave it blank
}
When I call on this method, I get a null pointer exception. Additionally, the for loop doesn't even matter.
class NPE() {
init {
refreshProperties()
}
var menuComponents: ArrayList<Double> = ArrayList()
fun refreshProperties() {
refreshJMenuComponents()
}
private fun refreshJMenuComponents() {
val i = menuComponents.size
println("$i is the length.")
for (index in 0 until menuComponents.size) {
val component = menuComponents[index]
println("Refreshed component: $component")
}
}
}
fun main() {
NPE()
}
This statement errors out too. I don't change menuComponents at all before I call these, so it should just be equal to a blank array list. I don't know why it's throwing a Null Pointer Exception.
menuComponents = arrayListOf(//component 1, component 2)
If I try running any of the previous statements on menuComponents now, it still throws a Null Pointer Exception. The value is not nullable, and I am explicitly setting it equal to something, so why is it erroring out at all? It should just not even compile if there is a null object somewhere? It compiles and then throws an exception.
Is this some sort of possible bug or am I just missing something?
I just needed to move the variable initialization above the init block.
class NPE() {
var menuComponents: ArrayList<Double> = ArrayList()
init {
refreshProperties()
}
fun refreshProperties() {
refreshJMenuComponents()
}
private fun refreshJMenuComponents() {
val i = menuComponents.size
println("$i is the length.")
for (index in 0 until menuComponents.size) {
val component = menuComponents[index]
println("Refreshed component: $component")
}
}
}
fun main() {
NPE()
}

How to add elements to CopyInWriteCollection using Kotlin style?

Assume we have a custom collection
class CopyOnWriteCollection<T> {
// returns copy of collection with new element
fun add(element: T): CopyOnWriteCollection<T> {
...
}
}
if i need to add several elements i would do something like this:
val newCollection = oldCollection
.add(1)
.add(2)
.add(3)
And newCollection contains elements from oldCollection and also contains 1,2,3.
Perfect!
But how can i add elements from another collection using forEach of map?
val collection = CopyOnWriteCollection()
(1..3).forEach { collection.add(it) } // this approach works only with mutable collections
You can use an imperative loop, or you can use the fold()function:
fun main() {
var collection = CopyOnWriteCollection<Int>()
var collection2 = collection
for (i in 1..3) {
collection = collection.add(i)
}
println(collection)
collection2 = (1..3).fold(collection2) { coll, i -> coll.add(i) }
println(collection2)
}
class CopyOnWriteCollection<T> {
private val list = mutableListOf<T>()
// returns copy of collection with new element
fun add(element: T): CopyOnWriteCollection<T> {
val copy = CopyOnWriteCollection<T>()
copy.list.addAll(this.list)
copy.list.add(element)
return copy;
}
override fun toString() = list.toString()
}
If the CopyOnWriteCollection class is under your control, I'd approach this by adding an addAll() method to it:
/** Returns copy of collection with new element. */
fun addAll(elements: Collection<T>): CopyOnWriteCollection<T> {
// ...
}
You could then call that with e.g.
val newCollection = oldCollection.addAll(listOf(1, 2, 3))
(Or you could take a vararg instead of a collection.)
That's likely to take a lot less time and memory.
(Also, if you really need to write your own collection class, I'd strongly recommend implementing Collection (or one of its subinterfaces if appropriate), or extending a class which does.  That will give access to the huge range of extension methods and other goodies in the stdlib.)

List or array is always empty in Kotlin

I'm trying to write simple Stack on Kotlin, but all data containers are always throws ArrayIndexOutOfBoundsException. I can't find out what can cause this problem:
class StackX(size: Int) {
private var maxSize: Int = size
private var stackArray: Array<Long> = arrayOf(maxSize.toLong())
private var top = -1
fun push(data: Long) {
stackArray[++top] = data
}
fun pop() : Long {
return stackArray[top--]
}
fun peek() : Long {
return stackArray[top]
}
fun isEmpty() : Boolean {
return (top == -1)
}
fun isFull() : Boolean {
return (top == maxSize -1)
}
}
Could you please explain me the right patter of arrays declaration in this case? I want just this:
int a[] = new int[10];
P.S. It's test code, I even doesn't call pop. It throws on push. I'm just trying to understand what's wrong with declaration.
This line is the problem
private var stackArray: ArrayList<Long> = arrayListOf().
It creates an array which length is 0.
Perhaps, you want something like this
val stackArray: LongArray = LongArray(size).
The problem is in your push() method.
private var stackArray: ArrayList<Long> = arrayListOf() // size = 0
private var top = -1
fun push(data: Long) {
stackArray[++top] = data // top = 0
}
What you're trying to do is to get the 0th element of an empty list.
Possible fix:
fun push(data: Long) {
stackArray.add(data)
++top
}
Updated.
Creating an int array of the specified size:
int[] a = new int[10]; // Java
val a = IntArray(10) // Kotlin
All elements are initialized to zero.
Creating a DataItem array:
DataItem[] b = new DataItem[10]; // Java
val b = arrayOfNulls<DataItem>(10) // Kotlin
All elements are initialized to null.