Return an Array<out String>? in Kotlin - string

I'm trying to read a list of string from a file, which is structured as a list:
ElemA
ElemB
ElemC
I need to save into this variable, which is defined as:
private var history: Array<out String>?
I made this method, but it doesn't works because it requires an Array? as output, but it founds an Array<(out) Any!>!
private fun loadHistory(): Array<out String>? {
val list = ArrayList<String>()
File("history").forEachLine { list.add(it) }
return list.toArray()
}
How can I solve?

As suggested by #jsamol in the comments.
You should use toTypedArray() instead of toArray() to get an array of the specific type.(ref)
toArray() returns new array of type Array<Any?>. (ref)
private fun loadHistory(): Array<out String>? {
val list = ArrayList<String>()
File("history").forEachLine { list.add(it) }
return list.toTypedArray()
}

Related

How is the best way to map UsbConfiguration object in Kotlin?

Hello actually I'm developing an app with the use of USB, I need return the UsbConfiguration from this map structure but the compiler error is:
Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly
This is the call from the method:
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun getConfiguration(index:Int?):
Map<String, Any> {
val device = usbDevice
val configuration: UsbConfiguration = device!!.getConfiguration(index!!)
val map = configuration.toMap() + ("index" to index)
return map
}
And this is the part with the problem specific in getInterface(it).toMap():
fun UsbConfiguration.toMap() = mapOf(
"id" to id,
"interfaces" to List(interfaceCount) {
getInterface(it).toMap() }
)
The code from library to the method getInterface(int index)
#NonNull
public UsbInterface getInterface(int index) {
throw new RuntimeException("Stub!");
}

When extending an interface, should we use object keyword?

I have two different pieces of code. In one i need to use object and in the second i'm not.
Can someone explain me the difference between the situation:
first Code:
private val onInitWebResponseHandler: VolleyHandler.WebResponseHandler = VolleyHandler.WebResponseHandler()
{
Thread(ParseJsonStringOnInit(WeakReference(this),
weakRefIOnAllScoresDataFirstFetched, it)).start()
}
Second Code:
val competitionOrderLevelComparator : Comparator<CompetitionObj> = object : Comparator<CompetitionObj> {
override fun compare(object1: CompetitionObj, object2: CompetitionObj): Int
{
return object1.orderLevel - object2.orderLevel
}
}
fun interface WebResponseHandler
{
fun onWebResponseFinished(jsonString:String?)
}
In addition how the first code, we can have () brackets if interface doesn't have a constructor?

How to get objects from list by data from map with condition and save to another map using Groovy

Looking for solution how to match objects from list with data from map with condition if object field starts with map values and save to another map with Groovy
i have map with some data
Map<String, String> dataMap = new HashMap()
dataMap.put("d1", "DATA1")
dataMap.put("d2", "DATA2")
dataMap.put("d3", "DATA3")
and list of DataElement objects
List<DataElement> elements = new ArrayList()
elements.add(new DataElement("TEXT1"))
elements.add(new DataElement("TEXT2"))
elements.add(new DataElement("DATA1_text1"))
elements.add(new DataElement("DATA2_text2"))
class DataElement {
public field;
public DataElement(String text){
this.field = text
}
public getField(){
return this.field
}
And i'am trying to get new Map where keys are values from first map and values are objects(field) from List with condition if object field starts with map value: Result should be:
[d1=DATA1_text1, d2=DATA2_text2]
My code is working but may be there is more elegant variant with using collectEntries:
list = new HashMap()
mapping = dataMap.each { key, v ->
elements.each { el ->
if (el.getField().startsWith(v)) {
list.put(key, el)
}
}
}
dataMap.collectEntries{k,v->
[k,elements.find{e-> e.getField().startsWith(v)} ]
}.findAll{k,v-> v} //to keep only non empty values

Empty set after collectAsList, even though it is not empty inside the transformation operator

I am trying to figure out if I can work with Kotlin and Spark,
and use the former's data classes instead of Scala's case classes.
I have the following data class:
data class Transaction(var context: String = "", var epoch: Long = -1L, var items: HashSet<String> = HashSet()) :
Serializable {
companion object {
#JvmStatic
private val serialVersionUID = 1L
}
}
And the relevant part of the main routine looks like this:
val transactionEncoder = Encoders.bean(Transaction::class.java)
val transactions = inputDataset
.groupByKey(KeyExtractor(), KeyExtractor.getKeyEncoder())
.mapGroups(TransactionCreator(), transactionEncoder)
.collectAsList()
transactions.forEach { println("collected Transaction=$it") }
With TransactionCreator defined as:
class TransactionCreator : MapGroupsFunction<Tuple2<String, Timestamp>, Row, Transaction> {
companion object {
#JvmStatic
private val serialVersionUID = 1L
}
override fun call(key: Tuple2<String, Timestamp>, values: MutableIterator<Row>): Transaction {
val seq = generateSequence { if (values.hasNext()) values.next().getString(2) else null }
val items = seq.toCollection(HashSet())
return Transaction(key._1, key._2.time, items).also { println("inside call Transaction=$it") }
}
}
However, I think I'm running into some sort of serialization problem,
because the set ends up empty after collection.
I see the following output:
inside call Transaction=Transaction(context=context1, epoch=1000, items=[c])
inside call Transaction=Transaction(context=context1, epoch=0, items=[a, b])
collected Transaction=Transaction(context=context1, epoch=0, items=[])
collected Transaction=Transaction(context=context1, epoch=1000, items=[])
I've tried a custom KryoRegistrator to see if it was a problem with Kotlin's HashSet:
class MyRegistrator : KryoRegistrator {
override fun registerClasses(kryo: Kryo) {
kryo.register(HashSet::class.java, JavaSerializer()) // kotlin's HashSet
}
}
But it doesn't seem to help.
Any other ideas?
Full code here.
It does seem to be a serialization issue.
The documentation of Encoders.bean states (Spark v2.4.0):
collection types: only array and java.util.List currently, map support is in progress
Porting the Transaction data class to Java and changing items to a java.util.List seems to help.

How to Implicitly Convert an Enumerable of a type with Implicit Conversion Operators in C# 4.0

Given:
public struct Id
{
readonly int m_id;
public Id(int id)
{ m_id = id; }
public static implicit operator int(Id id)
{ return id.m_id; }
public static implicit operator Id(int id)
{ return new Id(id); }
}
Can you implicitly convert an
IEnumerable<int>
to
IEnumerable<Id>
and vice versa. In some way. Note that
var ids = new int[]{ 1, 2 };
ids.Cast<Id>();
does not appear to work and covariance does not appear to be working in this case, either. Of course, doing a select will work i.e.:
ids.Select(id => new Id(id));
But I am looking for something that would make this work implicitly, so writing:
IEnumerable<Id> ids = new int[]{ 1, 2 };
And yes, I know this can be written as:
IEnumerable<Id> ids = new Id[]{ 1, 2 };
But the issue is in cases where the enumerable of ints comes from a different source, such as a file for example.
I am sorry if there already is an answer for this, but I could not find it.
According to this answer what you want is not possible. But you can get close by not implicitly casting your id but your collection. Like this :
public class Ids : List<int>
{
public static implicit operator Ids(int[] intArray)
{
var result = new Ids();
result.AddRange(intArray);
return result;
}
}
then this is possible :
Ids t = new [] { 3,4 };
What's wrong with:
IEnumerable<int> data = GetDataFromSource();
IEnumerable<Id> ids = data.select(id => new Id(id));

Resources