Gson deserialize Array of Integers in kotlin - list

Normally, when I deserialize a json-String I use something like this:
val result = gson.fromJson<myObject>(json, object : TypeToken<myObject>() {}.type)
But now I want to deserialize a simple List of Int and I cannot build an object for that.
The json-String is extremely simple and looks like this:
[1,35,37,255]
and I would like to save it into a List but
val result = gson.fromJson<List<Int>>(json, object : TypeToken<List<Int>>() {}.type)
does not work because there is no object. How should I handle such an easy structure? Is it better without gson eg with explode?

I think you in kotlin you don't need to use TypeToken you can go like
val result = gson.fromJson<List<Int>>(json)
here if you want to read more

val gson = Gson()
val itemType = object : TypeToken<List<Item>>() {}.type
itemList = gson.fromJson<List<Item>>(itemListJsonString, itemType)

Related

Kotlin List and MutableList: two different references, pointed to the same collection object

Could you give an example to this quotation:
A key thing to keep in mind when working with collection interfaces is that read-only collections aren’t necessarily immutable. If you’re working with a variable that has a read-only interface type, this can be just one of the many references to the same collection. Other references can have a mutable interface type
I want to write a function that adds elements to some collection, while creating a val someCollection: List <> in the fun main(). I can do this through the var someCollection: List <> = funAdd(someCollection.toMutable), but can I do it like this without using a variable var?
Example
fun addEl(numbers:MutableList<Int>):List<Int>{
for (i in 1..10){
numbers.add(i)
}
return numbers.toList()
}
fun main(args: Array<String>){
var readOnlyNumbers: List<Int> = emptyList()
readOnlyNumbers = addEl(readOnlyNumbers.toMutableList())
println(readOnlyNumbers.size)
}
Can I avoid using var and reassigment readOnlyNumbers or not?
Here are various ways of rewriting your code without using var:
fun addEl(numbers:MutableList<Int>):List<Int>{
for (i in 1..10) {
numbers.add(i)
}
return numbers.toList()
}
fun main(args: Array<String>){
val readOnlyNumbers: List<Int> = addEl(mutableListOf())
println(readOnlyNumbers.size)
}
or simply
fun createEl(): List<Int> {
return (1..10).toList()
}
fun main(args: Array<String>){
val readOnlyNumbers = createEl()
println(readOnlyNumbers.size)
}
To answer this part:
Could you give an example to this quotation:
A key thing to keep in mind when working with collection interfaces is that read-only collections aren’t necessarily immutable. If you’re working with a variable that has a read-only interface type, this can be just one of the many references to the same collection. Other references can have a mutable interface type
This is simply talking about situations like this:
val mutableList: MutableList<Int> = mutableListOf<Int>()
val list: List<Int> = mutableList
println(list) // []
mutableList.add(0)
println(list) // [0]
Even though list has type List<Int> and not MutableList<Int>, its contents have changed.
Note that this is an example of
I want to write a function that adds elements to some collection, while creating a val someCollection: List <> in the fun main().
as well, but I wouldn't recommend writing this code; go with one of JB Nizet's versions.

More idiomatic way to initialize this kotlin list?

I want to have an immutable list, since I don't really need the mutability so it likely to just cause bugs. However, the list is a lateinit var declared at the class level.
I want to initially populate the list with values from a loop somewhat like this:
for (items in someOtherCollection) {
val itemToAdd = doSomeProcessingOnThisData()
list.add(itemToAdd)
}
However, since the list is immutable, I can't call add(). Is there a better way to init a list such as this without simply adding all the values to a second, mutable list and then assigning it to an immutable list?
My current solution is this, but it just seems inefficient:
val tmpList = mutableListOf<Data>()
foos.forEach() {
val itemToAdd = doSomeProcessing()
foos.add(itemToAdd)
}
this.list = tmpList
If you want to make a new list processing some data in another collection, try this:
this.list = someOtherCollection.map {
doSomeProcessing()
}
Give this a read for a better understanding: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html

convert TreeMap<String,Object> to List<HashMap<String,Object>>

I have a TreeMap<String,Object> which contains Objects that are actually HashMap<String,Object>. I want to convert this to List<HashMap<String,Object>>. I was trying to convert it using Java 8 and wrote the following code which is giving compilation error due to conversion from List<Object> to List<HashMap<String,Object>>.
public static void main(String[] args) {
TreeMap<String,Object> treeMap = new TreeMap<String,Object>();
HashMap<String,Object> map1 = new HashMap<String,Object>();
map1.put("a",1);
map1.put("b","2");
map1.put("c",5);
treeMap.put("01",map1);
HashMap<String,Object> map2 = new HashMap<String,Object>();
map2.put("a",5);
map2.put("b","7");
map2.put("c",6);
treeMap.put("02",map2);
//this conversion is not working as Java is not allowing to convert from List<Object> to List<HashMap<String,Object>>
List<HashMap<String,Object>> list= treeMap.values().stream()
.collect(Collectors.toList());
}
Changing the TreeMap to TreeMap<String,HashMap<String,Object>> works but I don't want to make this change as I am passing this to a separate method which expects TreeMap<String,Object>.
Please suggest.
Well, you define the treeMap to have Object values, this is why values().stream() returns a Stream<Object>. Either change your contract or you'll need to cast the elements in the stream:
List<HashMap<String,Object>> list= treeMap.values().stream()
.map(element -> (HashMap<String,Object>)element)
.collect(Collectors.toList());
I would start by giving treeMap the proper types: TreeMap<String, HashMap<String, Object>>.
You can then wrap the map and pass new TreeMap<String, Object>(treeMap) to that other method.
Nicer, as it does not require a new map, would be to follow Sean's comment and change that method's parameter from TreeMap<String, Object> to TreeMap<String, ?>, if you are allowed to do that.

Scala classes and List

So my short code snippet looks like the following:
Source.fromFile(fileName).getLines().foldLeft(List[CsvEntry]())((csvList, currentLine) =>
currentLine match {
case pattern(organisation,yearAndQuartal,medKF,trueOrFalse,name,money) => new CsvEntry(organisation,yearAndQuartal,medKF.toInt,trueOrFalse.toInt,name,money) :: csvList
case default => csvList
The "fileName" is only the Name of the file, but it doesn't matter for my question.
And my csvList is defined like this:
type csvList = List[CsvEntry]
val list: csvList = List()
my class look like this:
class CsvEntry(val organisation: String, val yearAndQuartal : String, val medKF:Int, val trueOrFalse: Int, val name: String, val money:String){
override def toString = s"$organisation, $yearAndQuartal, $medKF,$trueOrFalse, $name, $money"
So my question is, whenever I am loading a file and writing it to my csvList it works, but when I am loading another 2nd file the old content gets overwirtten.
How can I change it in order to not get overwirtten, so it should only add it to the preceding data ?
The call beginning Source.fromFile... returns a list that you should then combine with the next call.
For example:
List("filename1", "filename2").map(processFile).flatten
where processFile is:
def processFile(fileName: String) = {
Source.fromFile(fileName).getLines().foldLeft... all the code in question
}
Nothing here can possibly get "overwritten", since there's no mutable state. Your type csvList and csvList in your foldLeft call are two very different things: the former is the type, the latter is the parameter.
Each time your snippet is executed, it returns a list of your CSV objects of a particular file. As an immutable list.
What you want is:
Make a function out of your snippet: def readFile(name: String): List[CsvFile]
Call it on the two files and save results to vals
Concat the two lists: list1 ++ list2

What type should my variable be declared as?

I am new to C# / OOP and am working on converting an existing application into .net 4.0 framework.
My code is as follows:
Class abc
private IList<string[]> GetReportBatchList()
{
List<string[]> rowList = new List<string[]>();
SqlParameter[] prm = { new SqlParameter("#rpt_doc_type_id", SqlDbType.Int, 9) };
prm[0].Value = 101;
try
{
.....
.....
.....
}
return rowList;
}
class xyz
using abc;
Private Function GenerateReport()
Try
{
Dim rptBatchList As ??????
rptBatchList = GetReportBatchList()
While rptBatchList.Read()
......
......
......
}
catch
{
......
}
What type should rptBatchList be declared as?
Since the return value of GetReportBatchList() has IList of string as its type, it makes sense that rptBatchList should be the same type.
Your second example is VB, but you say you are using C#, so...
For C# it would be IList<string[]>.
My VB is a little rusty, but I think it would be IList(Of String()).
Hmmm... is this a question about correct return types, or a question about translating C# into VB.Net?
According to the function definition you have, rptBatchList will be of type IList<string[]> - obviously declared in the correct syntax for VB.Net.
Further to that, because it is a list of string arrays, it doesn't have a Read() function, so maybe you were looking for something that derives from DbDataReader instead (like a SqlDataReader)? If you do intend to stick with the current definition then you can use either a foreach or a for loop to iterate over the list elements, or you can use Linq extensions and use something like this:
rptBatchList.ForEach(z => { z.ForEach(x => doSomethingWithThisResultString(x)); } );
although that can get messy fast - you probably want to just stick with a couple of nested foreach loops.