Convert Array<String> to ArrayList<String> - arraylist

How do I convert Array<String> to ArrayList<String> in Kotlin?
var categoryList : ArrayList<String>?=null
val list = arrayOf("None", "ABC")
categoryList = ArrayList(Arrays.asList(list))
I receive this error:
Error
Type inference failed. Expected type mismatch: inferred type is kotlin.collections.ArrayList<Array<String>!> /* = java.util.ArrayList<Array<String>!> */ but kotlin.collections.ArrayList<String>? /* = java.util.ArrayList<String>? */ was expected

You may be interested in toCollection to add the elements to any collection you pass:
categoryList = list.toCollection(ArrayList())
Note that to fix your specific problem you just need the spread operator (*). With the *-fix applied it would have worked too:
categoryList = ArrayList(Arrays.asList(*list))

Hope it'll help.
var categoryList : ArrayList<String>?=null
val list = arrayOf("None", "ABC")
categoryList = list.toCollection(ArrayList())

Another approach is use arrayListOf
categoryList =arrayListOf("None", "ABC")

The spread operator and arrayListOf is another option:
var categoryList : ArrayList<String>?=null
val list = arrayOf("None", "ABC")
categoryList = arrayListOf(*list)

import kotlin.collections.ArrayList
var arr:List<String>=["one","two"]<br>
val array_list:ArrayList<String>=ArrayList(arr)

Related

Why is "contains" or "in" not working in Kotlin

I'm currently working on a project with different functions.
One of the functions is supposed to take a map and a string as inputs, then compare the items in the map and string and create a new map with matching items.
This function is not working because "containsKey" always returns false.
"in" always returns fault.
I tried substituting the map with a mutable List and got the same results.
I tried this same code on kotlin playground, link; https://pl.kotl.in/zZm1Smz3Z
and it worked well but wouldn't work on the platform I am using.
The function is below
fun createVariable (stringList: String, mapNumber: MutableMap<String, String>):MutableMap<String, String> {
var mapOfNumber = mutableMapOf<String, String>()
var conList : MutableList<String> = mutableListOf()
var regex = Regex("\\s*=\\s*")
var regez = Regex("\\s+")
var numberList = stringList.split(regex).toMutableList()
for (i in 0.. numberList.size -1) {
if ( regez.matches(numberList[i])) {
numberList.removeAt(i)
}
}
if (mapNumber.containsKey(numberList[1])) {
mapOfNumber.put(numberList[0], (mapNumber[numberList[1]])?: "0")
}
print(mapOfNumber)
return mapOfNumber
}

what is the difference between var and val in extension properties?

I created extension properties and I'm having this problem
fun main(args: Array<String>) {
println(Animal("Mia",1,1.0))
}
class Animal(var name : String, var age : Int, var weight : Double)
var Animal.getXXX : String // compiler : Property must be initialized
get() = "$name, $age, $weight"
val Animal.getXXX : String // the compiler is running properly
get() = "$name, $age, $weight"
in the code above. why should i use val instead of var?
The error message is perhaps a bit confusing. For extension fields using var they are expected to have both a getter and a setter. Fields using val only need to have a getter (and can't have a setter). The following code works:
var Animal.getFoo : String
get() = "$name, $age, $weight"
set(value) { /* do something */ }
var is mutable and we can reassign or change its value. But we can't change val value.
The difference between var and val in extension properties is that while writing extension property if you use val you can only use get because you can not set value to it as it is immutable constant variable you can not use set() in val extension property
For Example
val String.extensionProperty
get() = "Value"
And if you want to make an extension property with var which you want to be mutable so you can set value into it as well and perform any other action while updating varaible.
For Example
var String.extensionProperty
get() = "Value"
set(value) {
println("variable has been updated with this data $value")
}

Converting SQL Query with Aggregate Function to Relational Algebra Expression in Apache Calcite - No match found for function signature

I'm trying to convert a SQL query to a relational algebra expression using the Apache Calcite SqlToRelConverter.
It works fine for this query (quotes are for ensuring lowercase):
queryToRelationalAlgebraRoot("SELECT \"country\" FROM \"mytable\"")
But on this query it fails:
queryToRelationalAlgebraRoot("SELECT \"country\", SUM(\"salary\") FROM \"mytable\" GROUP BY \"country\"")
with this error:
org.apache.calcite.sql.validate.SqlValidatorException: No match found for function signature SUM(<NUMERIC>)
It seems that somehow the SQL validator doesn't have aggregation functions like sum or count registered.
case class Income(id: Int, salary: Double, country: String)
class SparkDataFrameTable(df: DataFrame) extends AbstractTable {
def getRowType(typeFactory: RelDataTypeFactory): RelDataType = {
val typeList = df.schema.fields.map {
field => field.dataType match {
case t: StringType => typeFactory.createSqlType(SqlTypeName.VARCHAR)
case t: IntegerType => typeFactory.createSqlType(SqlTypeName.INTEGER)
case t: DoubleType => typeFactory.createSqlType(SqlTypeName.DOUBLE)
}
}.toList.asJava
val fieldNameList = df.schema.fieldNames.toList.asJava
typeFactory.createStructType(typeList, fieldNameList)
}
}
object RelationalAlgebra {
def queryToRelationalAlgebraRoot(query: String): RelRoot = {
val sqlParser = SqlParser.create(query)
val sqlParseTree = sqlParser.parseQuery()
val frameworkConfig = Frameworks.newConfigBuilder().build()
val planner = new PlannerImpl(frameworkConfig)
val rootSchema = CalciteSchema.createRootSchema(true, true)
// some sample data for testing
val inc1 = new Income(1, 100000, "USA")
val inc2 = new Income(2, 110000, "USA")
val inc3 = new Income(3, 80000, "Canada")
val spark = SparkSession.builder().master("local").getOrCreate()
import spark.implicits._
val df = Seq(inc1, inc2, inc3).toDF()
rootSchema.add("mytable", new SparkDataFrameTable(df))
val defaultSchema = List[String]().asJava
val calciteConnectionConfigProperties = new Properties()
val calciteConnectionConfigImpl = new CalciteConnectionConfigImpl(calciteConnectionConfigProperties)
val sqlTypeFactoryImpl = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT)
val calciteCatelogReader = new CalciteCatalogReader(rootSchema, defaultSchema, sqlTypeFactoryImpl, calciteConnectionConfigImpl)
val defaultValidator = SqlValidatorUtil.newValidator(new SqlStdOperatorTable(), calciteCatelogReader, sqlTypeFactoryImpl, SqlConformanceEnum.LENIENT)
val relExpressionOptimizationCluster = RelOptCluster.create(new VolcanoPlanner(), new RexBuilder(sqlTypeFactoryImpl))
val sqlToRelConfig = SqlToRelConverter.configBuilder().build()
val sqlToRelConverter = new SqlToRelConverter(planner, defaultValidator, calciteCatelogReader, relExpressionOptimizationCluster, StandardConvertletTable.INSTANCE, sqlToRelConfig)
sqlToRelConverter.convertQuery(sqlParseTree, true, true)
}
}
The problem with the code is that new SqlStdOperatorTable() creates a validator which is not initialized. The correct way to use SqlStdOperatorTable is to use SqlStdOperatorTable.instance().
I found the solution after emailing the dev#calcite.apache.org mailing list. I would like to thank Yuzhao Chen for looking into the question I had and pointing out the problem with my code.
I am not familiar with the api but your SQL needs group by country. And if a tool is to take this output and use it, it will probably require that you name the column too with an alias.

Simple casting in Kotlin/Java

I have an object User defined as below
class User(){
var id: Int? = null
var name: String? = null}
For certain reasons, I have to create new object User of same parameters and I have to copy data from old to new type.
class UserNew(){
var id: Int? = null
var name: String? = null}
I was looking for easiest way to convert from old type to a new one. I want to do simply
var user = User()
var userNew = user as UserNew
But obviously, I am getting This cast can never succeed. Creating a new UserNew object and set every parameter is not feasible if I have a User object with lots of parameters. Any suggestions?
as is kotlin's cast operator. But User is not a UserNew. Therefore the cast fails.
Use an extension function to convert between the types:
fun User.toUserNew(): UserNew {
val userNew = UserNew()
userNew.id = id
userNew.name = name
return userNew
}
And use it like so
fun usingScenario(user: User) {
val userNew = user.toUserNew()
If you don't want to write a boilerplate code, you can use some libraries that will copy values via reflection (for example http://mapstruct.org/), but it's not the best idea.
To achieve you can Simply use Gson and avoid boilerplate code:
var user = User(....)
val json = Gson().toJson(user)
val userNew:UserNew =Gson().fromJson(json, UserNew::class.java)
you should follow this logic for this case.
note: #Frank Neblung answer i implemented
fun main(args: Array<String>) {
val user = User()
user.id = 10
user.name = "test"
var userNew = user.toUserNew()
println(userNew.id) // output is 10
println(userNew.name)// output is test
}
class User()
{
var id: Int? = null
var name: String? = null
fun toUserNew(): UserNew {
val userNew = UserNew()
userNew.id = id
userNew.name = name
return userNew
}
}
class UserNew() {
var id: Int? = null
var name: String? = null
}
You have two options. Either create interface and implement it in both classes. then you can use this interface in both places (User,UserNew) If this is not what you want, i would use copy constructor in UserNew taking User as parameter, You can create new
NewUser nu = new UserNew(userOld)
if you have lots of properties answer from ppressives is way to go
To achieve that you can use the concept of inheritance:
https://www.programiz.com/kotlin-programming/inheritance
Example:
open class Person(age: Int) {
// code for eating, talking, walking
}
class MathTeacher(age: Int): Person(age) {
// other features of math teacher
}

How do I initialize Kotlin's MutableList to empty MutableList?

Seems so simple, but, how do I initialize Kotlin's MutableList to empty MutableList?
I could hack it this way, but I'm sure there is something easier available:
var pusta: List<Kolory> = emptyList()
var cos: MutableList<Kolory> = pusta.toArrayList()
You can simply write:
val mutableList = mutableListOf<Kolory>()
This is the most idiomatic way.
Alternative ways are
val mutableList : MutableList<Kolory> = arrayListOf()
or
val mutableList : MutableList<Kolory> = ArrayList()
This is exploiting the fact that java types like ArrayList are implicitly implementing the type MutableList via a compiler trick.
Various forms depending on type of List, for Array List:
val myList = mutableListOf<Kolory>()
// or more specifically use the helper for a specific list type
val myList = arrayListOf<Kolory>()
For LinkedList:
val myList = linkedListOf<Kolory>()
// same as
val myList: MutableList<Kolory> = linkedListOf()
For other list types, will be assumed Mutable if you construct them directly:
val myList = ArrayList<Kolory>()
// or
val myList = LinkedList<Kolory>()
This holds true for anything implementing the List interface (i.e. other collections libraries).
No need to repeat the type on the left side if the list is already Mutable. Or only if you want to treat them as read-only, for example:
val myList: List<Kolory> = ArrayList()
I do like below to :
var book: MutableList<Books> = mutableListOf()
/** Returns a new [MutableList] with the given elements. */
public fun <T> mutableListOf(vararg elements: T): MutableList<T>
= if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))
Create Mutable list of nullable String in kotlin
val systemUsers: MutableList<String?> = mutableListOf()
It is absolutely valid to use the MutableList() function of the Kotlin collections that intentionally looks like a constructor. This function is in general very useful to know because it can also consume an initialization function that pre-fills all values of a (non-empty) list.
val emptyListOfTypeUnit = MutableList(0) {}
val emptyListOfTypeInt = MutableList(0) { 0 }
val verboseEmptyListOfTypeInt = MutableList<Int>(0) { 0 }
val emptyListOfTypeString = MutableList(0) { "" }
val verboseEmptyListOfTypeString = MutableList<String>(0) { "" }
val emptyListOfTypeKolory = MutableList(0) { Kolory() }
val verboseEmptyListOfTypeKolory = MutableList<Kolory>(0) { Kolory() }
Disclaimer: I was introduced to this in the Jetbrains Academy course for Kotlin developers, which is unfortunately not public. Therefore, I cannot link a reference here. Sorry.