Adding char to List<Char> in kotlin - kotlin

I am trying to create List<Char> from String in Kotlin but it seems there is no inbuilt function is provided by lib. Also casting will generate error. So here is what I am doing. Please let me know if I am missing something in question. (Or we can say converting string to List<Char> in Kotlin).
var stringVal = "ABC"
var genList:List<Char> = arrayListof()
var count = 0
while (stringVal.length == genList.size) {
// way to add stringVal to genList
count++
}

The answer given by #Moira is definitely the way to go here, I would accept it.
However, the question was about adding an element to a List<Char>, which isn't possible in Kotlin because a List is immutable and yours gets initialized as an empty one, so it will stay empty.
Use a MutableList<Char> and simply add single Chars to it if you need it:
fun main(args: Array<String>) {
var genList = mutableListOf<Char>()
genList.add('a')
genList.add('A')
genList.add('B')
genList.add('C')
println(genList)
}
Output:
[a, A, B, C]

val chars = "ABC".toList()
CharSequence has a to(Mutable)List extension function defined in kotlin.text.
fun CharSequence.toList(): List<Char>
Returns a List containing all characters.
kotlin-stdlib / kotlin.text / toList
fun CharSequence.toMutableList(): MutableList<Char>
Returns a MutableList filled with all characters of this char sequence.
kotlin-stdlib / kotlin.text / toMutableList
Kotlin's standard libraries have hundreds of utility functions like this, so chances are that most of the time what you want already exists.
Many standard types that conceptually model some sort of iterable data, but are not Iterable, have extensions defined on them that are equivalent to those in kotlin.collections.

Related

Is it possible to implement sequence programming with vararg in Kotlin?

I've been trying sequence programming for processing the data I get from the vararg argument. I want to multiply every number in the list and add it to the new array list. Is it possible to use sequences.
I attach the code below:
fun main() {
val number = asList(10, 20, 30, 40, 50)
print(number)
}
fun <T> asList(vararg input: T): List<T> {
val result = ArrayList<T>()
input.map {it * 2}.foreach(result.add(it))
return result
}
Here is the error I get:
enter image description here
Yes, it's possible to create a sequence from a vararg; I'll come back to that later.
First, the main problem in the code above is that, unfortunately, it can't be done generically.  The error you're getting is because T could be any type, and most types can't be multiplied, so the compiler is telling you that you can't do the * 2.
You might think of restricting T to subclasses of Number, but that doesn't help.  (Number is a very weak type; it doesn't let you do any arithmetic, probably because you can't tell what type the result would have to be, nor what rounding or overflow might occur.  All it lets you do is convert the value to specific types.)
But if you remove the type parameter and code it for a particular numeric type, such as Int, then it can work fine.
There are also spelling and syntax errors in the code around the foreach call.  Fixing those too gives e.g.:
fun asList(vararg input: Int): List<Int> {
val result = ArrayList<Int>()
input.map{ it * 2 }.forEach{ result.add(it) }
return result
}
That's doing a lot of unnecessary work, though; the map() already returns a list, so there's no point in creating a second list and copying to it element-by-element!  Also, the name is misleading.  So it could just be:
fun asListDoubled(vararg input: Int) = input.map{ it * 2 }
Your question mentioned sequences; but your code uses normal eager lists.  If you want a lazily-evaluated sequence, you can just add an asSequence() call, e.g.:
fun asSequenceDoubled(vararg input: Int) = input.asSequence().map{ it * 2 }
But note that this now returns a Sequence<Int>, not List<Int>, so you can go on and do further lazy operations on it.  (If you want a List<Int>, then you can just append a toList() call — but there's little point in using a sequence only for the doubling, as the sequence overhead is probably far higher than any saving.)

Kotlin: Define function for vararg and collection

Let's say for examples sake that I wanted to write my own sum function, which can take either a collection of ints or vararg ints, like in the following:
fun sum(ints: Collection<Int>): Int {
var result = 0
for (i in ints)
result += i
return result
}
fun sum(vararg ints: Int) = sum(ints.toSet())
Is there a better/idiomatic way to define a function for both parameter types? In many cases I only use such functions for one or two element, so wrapping it with listOf() outside of the function every time seems clunky to me.
I think there is no a better way of doing that. You can either use your example or this one:
fun sum(ints: Collection<Int>) = sum(*ints.toIntArray())
fun sum(vararg ints: Int): Int {
var result = 0
for (i in ints)
result += i
return result
}
Is there a better/idiomatic way to define a function for both
parameter types?
Since both are different types so it's not possible with a function only. You approach is okay.
But you pass an Array as vararg argument using spread operator (*)

is there any way I send a nullable Function<T,R> as parameter in Kotlin?

I am trying to use the public interface Function (as I learned it in Java) in Kotlin.
For this I created my method
fun foo(input: List<String>, modifier1: Function<List<String>>? = null){
}
as far I remember here I should be able to do modifier1.apply(input)
but seems like it is not possible (it is possible to do modifier1.apply{input} though)
Reading more about it I found this:
Kotlin: how to pass a function as parameter to another?
So I changed my method signature to this:
fun foo(input:String, modifier2: (List<String>) -> (List<String>){
}
Here I am able to do modifier2(input)
and I can call foo this way
service.foo(input, ::myModifierFunction)
where
fun myModifierFunction(input:List<String>):List<String>{
//do something
return input
}
So far this seems possible but it is not acceptable to have the function reference as nullable, is there any way I can do that? or use Function ?
You were using kotlin.Function instead of java.util.function.Function in your first example. Note that the latter takes 2 generic types: 1 for the incoming parameter and 1 for the resulting one.
The apply method you saw is the default Kotlin one: apply, not the one of Java's Function-interface.
If you really want to have the Java-function as nullable type the following should work:
fun foo(input: List<String>, modifier1: java.util.function.Function<List<String>, List<String>>? = null) {
modifier1?.apply(input) ?: TODO("what should be done if there wasn't passed any function?")
}
Kotlin variant for the same:
fun foo(input: List<String>, modifier1: ((List<String>) -> List<String>)? = null) {
modifier1?.invoke(input) ?: TODO("what should be done if there wasn't passed any function?")
}
Maybe also a default function, such as { it } instead of null might better suite your needs? (Java variant would be Function.identity()):
// java modifier1 : Function<List<String>, List<String>> = Function.identity()
// kotlin modifier1 : (List<String>) -> List<String> = { it }
You can make the reference nullable simply with ? — the only wrinkle is that the whole function type needs to be in parens first:
fun foo(input: String, modifier2: ((List<String>) -> List<String>)? = null) {
}
As required, modifier2 is optional; if specified, it may contain null, or it may contain a function taking and returning a list of strings.
As mentioned in another answer, kotlin.Function is not the same as java.util.function.Function — though in practice you shouldn't need to refer to either directly, as the -> notation is simpler.
If you want to pass in a function that takes List<String> as its parameter and returns nothing meaningful, the type for you is Function1<List<String>, Unit>. The method name for invoking a function is invoke(), which you could also do with just regular parentheses, if it wasn't nullable. All in all, your code could look something like this:
fun foo(input: List<String>, modifier1: Function1<List<String>, Unit>? = null) {
modifier1?.invoke(input)
}
The 1 in the typename of Function1 means that it's a one parameter function, there's also Function0, Function2, etc.
The Function type on its own is not something you can use to call that function, as it's an empty marker interface. All functions implement this regardless of how many parameters they have.

ArrayList<String>() vs arrayListOf<String>()

I was going through some Kotlin basics and found two syntaxes.
ArrayList<String>()
And
arrayListOf<String>()
What is the difference between these two as both are part of Kotlin.Collections?
arrayListOf<T>() is mainly there for your convenience. vararg-functions usually come with a (sometimes negligible) performance impact and switching between the arrayListOf(someElements...) and arrayListOf() without that convenience method would basically delegate that problem to you as a programmer. You have to know it and you would have to change that code to ArrayList(), if such an impact is affecting you and if that convenience function wouldn't exist.
arrayListOf() is basically just that. It returns ArrayList() and it is inlined. That's just convenient, so that you don't really have to think about it, when you switch back and forth between arrayListOf(someElements) and arrayListOf().
That having said: there is no difference between arrayListOf() and ArrayList() as also others have already mentioned and arrayListOf(elements) is the convenience variant to construct an ArrayList with the given elements.
arrayListOf is a function, that has optional variable length arguments
In case of using it without arguments, there is no difference
arrayListOf<T>()
is just an extension function that looks like this:
public inline fun <T> arrayListOf(): ArrayList<T> = ArrayList()
it a function is right but is use of like this
here in function used set() function of arrayListOf() is used to set the given element at specified index and replace if any element already present at that index
fun main(args: Array<String>){
val list: ArrayList<String> = arrayListOf<String>()
list.add("Ajay")
list.add("Vijay")
list.add("Prakash")
println(".......print list.......")
for (i in list) {
println(i)
}
println(".......arrayList.set(2,\"Rohan\").......")
list.set(2,"Rohan")
println(".......print ArrayList.......")
for (i in list) {
println(i)
}
}
Output
.......print list.......
Ajay
Vijay
Prakash
.......list.set(2,"Rohan").......
.......print list.......
Ajay
Vijay
Rohan
When creating an empty array, you can use either:
val emptyArray1 = ArrayList()
val emptyArray2 = arrayListOf()
But when creating an array from existing elements, you have to use one or the other depending on whether the existing elements are already in a collection or you want to specify them individually:
val arrayFromCollection = ArrayList(hashMap.keys)
val arrayFromElements = arrayListOf("1", "2", "3")
Note that you can use the spread operator to pass an existing collection into arrayListOf as individual elements, but if the collection is anything other than another array, you also need to convert it to an array. This probably isn't worth the extra verbosity:
val arrayFromCollectionVerbose = arrayListOf(*hashMap.keys.toTypedArray())

Difference between Any type and Generics in Kotlin

Suppose I have the following function definition.
fun<T> parse(a: Any): T = when (a) {
is String -> a
else -> false
}
I guessed it should be valid. However, the IntelliJ IDEA linter shows a type mismatch error
That being said, I would change the return type of my parse function to Any, right? So that, what is the difference between using Any type and Generics in Kotlin? In which cases should use each of those?
I did read the following question but not understood at all about star-projection in Kotlin due to the fact I am quite new.
Your return type it defined as T, but there is nothing assuring that T and a:Any are related. T may be more restrictive than Any, in which case you can't return a boolean or whatever you provided for a.
The following will work, by changing the return type from T to Any:
fun<T> parse(a: Any): Any = when (a) {
is String -> a
else -> false
}
Any alternate option, if you really want to return type T:
inline fun<reified T> parse(a: Any): T? = when (a) {
is T -> a
else -> null
}
Your example does not use T and thus it's nonsense to make it generic anyways.
Think about this: As a client you put something into a function, e.g. an XML-ByteArray which the function is supposed to parse into an Object. Calling the function you do not want to have it return Any (Casting sucks) but want the function return the type of the parsed object. THIS can be achieved with generics:
fun <T> parse(xml: ByteArray): T {
val ctx: JAXBContext = JAXBContext.newInstance()
val any = ctx.createUnmarshaller().unmarshal(ByteArrayInputStream(xml))
return any as T
}
val int = parse<Int>("123".toByteArray())
val string = parse<String>("123".toByteArray())
Look at the method calls: You tell with generics what type is expected to be returned. The code is not useful and only supposed to give you an idea of generics.
I guessed it should be valid
Why would it be? You return a String in one branch and a Boolean in the other. So the common type for the entire when expression is Any and that's what the compiler (and IDEA) says is "found". Your code also says it should be T (which is "required").
Your generic method should work for any T, e.g. for Int, but Any isn't a subtype of Int and so the code isn't valid.
So that, what is the difference between using Any type and Generics in Kotlin?
This is like asking "what is the difference between using numbers and files": they don't have much in common in the first place. You use generics to write code which can work with all types T (or with all types satisfying some constraint); you use Any when you want the specific type Any.