Arrays seems weird (beginner help with arrays)

Hi everybody.
Im not new to coding, but absolute rookie, beginner to Java and (my choice of learning) kotlin.

First thing that came up was arrays and how different they are.

What i want to achieve is this:
var myArray=new array()
or
var myArray=new array(1,2,3,4,5,6)
or
var myArray=new array(“String1”,“String2”,“String3”)
or even
var my Array=new array(objectid1,objectid2 and so on)

In other words, i need a way to declare arrays on my choice without give em a type like Any, Int, TextView or whatever, because i need mixed arrays. Could be more dimensional arrays too like
var my Array=new array(new array(1,2,3),new array(5,6,7))

Yes, array as mentioned is no part of kotlin, so i try to create a class array like
class array(value):Array{
return this
}

And of course i need some functions in in like
class array(value):Array{
fun splice(key:Int,Len:Int){
//code
}
return this
}

and so on.
So i need to be able to do something like this
myarray.splice(2,1)
myarray.push(“New Element”)

and so on.

I don’t need advice how to do a splice or a push function. Im going to figure that out by myself (i want to learn), but i need advice for the class itself, so that it returns my array
How can i achieve that?

Have you seen the stdlib function arrayOf()? That seems to do just what you want.

Though I’d suggest considering using a List instead (e.g. with listOf()).

In Java, arrays were the original data structure, and have their own syntax and behaviour. In Kotlin, though, they don’t have any special syntax, and look just like lists and other objects. They do still have some restrictions, though: they can’t be resized, don’t work well with generics, and because they’re not part of the Collections framework you can’t use them in the most of the ways you can use collections, lists, sets, maps, &c. Lists are much more flexible and powerful, so unless you need arrays for interoperability, you’ll probably find it easier to use lists.

i came along arrayOf for my very first projects. I also came along list, but to be honest, i haven’t got the differences between Array, List, mutableList, ArrayList.

As i said. Im an absolute Beginner

Is lists a “don’t care about types” way for mixed arrays that works as needed, or do lists have limitations?

I appolgize for my questions. I guess a lot of you guys think “gosh, read the f…ck…g manual”. I did, but english is not my native language, so i struggle alot to get it. And unfortunately there is no manual in my language.

Unfortunately Kotlin cares about types, so there isn’t really some container that doesn’t.
You can declare everything as as MutableList<Any> and try to use that. In Kotlin all types inherit from Any, so you can add whatever you want to something of type MutableList<Any>.
See https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-list-of.html for how to create some.

Said that, you will have to do some casting from Any to some other type if you want to do anything with the content of such a container.

2 Likes

Think of a list as a resizeable array (one you can insert and remove items from), that also plays nicely with generics and with the whole collections framework.

Lists care about types just as much as arrays do; but of course in Kotlin types are inferred, so you rarely have to specify them. (One exception is for empty arrays and lists, where there’s nothing to infer from.)

And List is an interface, so it gives you the option of swapping out different implementations, e.g. for performance reasons. (Though the default is usually perfectly good.) ArrayList is one such implementation; it’s pretty good for most things, but it’s generally better to refer only to the interface if you can.

However, that highlights the other main difference from arrays: you can have immutable ones. In Kotlin (unlike Java), List is read-only, and has no methods for changing the list; instead, there’s a subinterface called MutableList which has those. So that gives you much more control over modifications. (There are similar Set/MutableSet, Map/MutableMap, and Collection/MutableCollection interfaces too.)

That’s why there are both listOf() and mutableListOf() functions. If you don’t need to change the list after creating it, the former can prevent some bugs, improve your documentation, promote multi-threaded usage, and lets you use it in more ways. (For those who understand the term: it’s covariant, while mutable lists are invariant.)

Finally, the Kotlin docs are reasonably good; if there are any points you’re having trouble understanding, perhaps you should post them here (or in the Kotlin issue tracker) so they can be improved.

2 Likes

Thanks a lot to both of you.
This clearified a lot to me.

But it also mean that i can’t solve this. But there must be a way.

Backgroundstory is pretty easy

To me (a script language coder like javascript and the obsolete actionscript, and yes i know both of em has nothing to do with java at all) it’s kind of inefficent to do

var something:Array = arrayOf (or listOf( and so on eveytime it’s needed. And that is for a reason.

First of all the types. As you mentioned above (must be defined for each array).
This makes it pretty hard for dynamic content e.g. Databasecoding and so on but also dynamic code itself by runtime.

Next is the initiation (setting of the array)
I can’t define an empty array and give it the values later.
The only way is using laterinit, which woks in the main class only, but not in other classes.

Well. That is my thoughs about it, but never mind :slight_smile:
I’ll find a way

Thanks

One last question to arrays (i hope so)

I’ve managed to get my array class running without any errors like this

var a=array()

But now i need to know, how i can di that

var a=array(1,2,3,4,5)

my class looks like this

class array(e:Array){

}
Is there a way for kotlin to recognize all given arguments as array elements?
Because right now it expects one argument. But an array has multiple vaules

I hope you know what i mean

Yes, you can. You just aren’t used to strongly typed languages.

You can use the Any type. Any can be anything and you can check the type with the is keyword if (something is String) ..... Many libraries will represent JSON, for example, objects as Any where the item is either null, Long, Double, String, List, or Map<String, Any>. Map<String, Any> is the strongly typed equivalent of a json object. Keys that are strings and values that can be anything. But because such dynamic code can lead to runtime errors (just like with javascript) using such code is discouraged.

Generally there are compiler plugins or annotation processors for these cases that generate type safe code to do what you need (generally this is related to serialization/persistence) and they hide the more dynamic internals.

If you give some more details, someone can likely point you in the right direction for the appropriate tool.

For every read-only collection, there is also a mutable variant. See mutableListOf, mutableMapOf, etc. Arrays are not read-only but they can’t be resized. If you want to add items, use a MutableList (created with mutableListOf).

fun main() {
    val myList = mutableListOf<Int>()
    myList += 1
    myList += 2
    println(myList)
}
1 Like

Yes you can use vararg to specify a variable number of arguments (see this reference page).

I learned did a lot of my early coding on AS3 (ActionScript3) and Lua. In many dynamic languages you’ll find a lot of reliance on collection heavy APIs (Groovy and Python for example). Instead of returning an object with structured fields of data they’ll return an array (or usually a list or tuple). Instead of supporting named arguments they take a map (aka dict) as a single parameter.

In a statically typed language, you’ll find you almost always structure what used to be a generic data structure into a class with named fields and types. Coming from a scripting language I would expect one to have to adapt to not using arrays and dicts everywhere.

Another thing to get used to is that you’ll rarely need to create a collection by specifying all elements outside of learning examples. It’s not every day that you’ll use something listOf("Apple", "Orange", "Banana") instead you’ll likely be creating a collection from iteration or other existing sources (fruits.map { it.name }.toList()).

It may sound inefficient to write out listOf() everywhere–and it might be. But if you find you are manually creating lists often, it’s likely a sign your not structuring your data.
In Groovy and Python, I’ll run into manually creating lists and maps everywhere since their APIs require lots of arrays.

If you really want a list of anything, first ask yourself “why”? In practice, you might find you really need a list of some other structured group of data. For example, consider you are storing a list of ["Bob", 15, "Alice", 22, "John" 56] as a List<Any>. What you’re really storing is a Person with a name and age. So instead formalize this structure as a class data class Person(val name: String, val age: Int) and store a List<Person> instead.

That’s correct, arrays can’t change size. Under the hood, they reserve the memory they need to keep its references to its content. @gidds has a very nice explanation of lists so I’ll just add this: Arrays are low-level things. You almost always want to use List instead.

Since you’re looking to create your own list-style data structure, I’d recommend starting with something like this:

// Only for learning. In a real program use the existing List<String> instead.
// Only for learning. Extend `List<T>` and use a generic class if making your own list data structure.
// Notice "vararg" is used to accept any number of arguments. For example, StringList("one", "two", "three").
class StringList(vararg startingElements: String) {
    private val elements = startingElements.toMutableList() // Here's our backing list that holds all of our real items.
    val size get() = elements.size
    
    fun add(element: String) {
        elements += element
    }
    fun get(index: Int): String {
        return elements.get(index)
    }
}

fun main() {
    val strings = StringList("one", "two", "three")
    println("Size: ${strings.size}")
    println("Index 0: ${strings.get(0)}")
    println("Index 1: ${strings.get(1)}")
    println("Index 2: ${strings.get(2)}")
    strings.add("four")
    println("Index 3: ${strings.get(3)}")
}

Again, only for learning. Outside of learning, you shouldn’t ever need to implement the basic data structures like the various lists (ArrayList, LinkedList, etc). It’s nice to reinvent the wheel at least once to better understand it :slight_smile:

Here are some links that might help:
Kotlin’s existing Array class

@gidds already posted this one but I’ll include it as well since it’s so valuable: https://kotlinlang.org/docs/reference/collections-overview.html
^ Notice that this is only the overview and more detail can be found on collections in Kotlin on the next few pages of the reference under the “Collections” section.

1 Like