I am a beginner in this field, I want to create a list of float values in kotlin
Example: In python
myList=[]
mylist.append(1.5)
mylist.append(2.5)
but how to do this in kotlin
We need to specify the list element's data type (Float in this case) when initializing empty mutable list using mutableListOf().
val myList = mutableListOf<Float>()
myList.add(1.5f)
myList.add(2.5f)
Use the listOf function:
val listOfFloats: List<Float> = listOf(1.1f, 2.2f, 3.3f)
In kotlin you can make a list like this
var myList: List<Int> = listOf<Int>(1, 2, 7, 9);
But if you want to push an item to the list you need to make it a mutable list. So I would say that you use a MutableList instead of a List
So it looks like this
var myList : MutableList<Int> = mutableListOf<Int>(); //You can add initial values inside the parentheses
myList.add(10);
myList.add(20);
Related
I have:
var myList: MutableList<MutableList<Int>>
and I want to dynamically create a list (i, j) which are Int and it is to the myList.
I tried
myList.add(mutableListOf(i,j))
But it doesn't work.
Firstly I get error: variable 'myList' must be initialized
And I am not sure that's the right way to make a list on the go and add it to a list of lists
As the error mentions, you have to initialize the list before using it.
var myList: MutableList<MutableList<Int>> with this you just declare its type.
var myList = mutableListOf<MutableList<Int>>() with this you have empty list. After that you can freely add another list inside it as an element.
initialize the list
var myList: MutableList<Int> = ArrayList()
This feature is inspired by TypeScript which allows us to create arrays based on the property of another class, whatever that property's type is.
For example assume you have this class in Kotlin:
class Person(
val name: String,
val age: Int
)
And later, somewhere else in the code I want to have a list of names, so I would do something like this:
val namesList = List<Person::name>()
And Kotlin will know that this will be equivalent to List<String>() at compile time.
This avoids me to manually propagate the type of a field I already declared in one place. Plus, if one day the name type changes from String to something else, all the collections would get updated automatically.
Can this be done in Kotlin?
No, Kotlin is very explicit about types. It is a strongly-typed language.
Maybe the closest you could do is define a type alias next to your class and use that:
typealias PersonName = String
data class Person(val name: PersonName, val age: Int)
and then:
val namesList = mutableListOf<PersonName>()
However, in most cases you don't have to explicitly write the types anyway because they can be inferred.
// Is a List<String> and would automatically update if name type changed
val nameList = personList.map(Person::name)
// Or to get an empty mutable list:
val nameList = emptyList<Person>().map(Person::name).toMutableList()
The standard thing to do is to use map to extract the type you need:
val people = listOf(
Person("a", 1),
Person("b", 2),
Person("c", 3),
)
val names = people.map { it.name } // statically inferred to List<String>
If you changed the type of name to something else, you wouldn't need to change the val names = people.map { it.name } line - the new type will be inferred automatically.
As per leetcode question here I am required to return List<List<Int>> type for Kotlin submission.
I tried using listOf() but unable to create.
My another guess was to use LinkedList of type List:
var result: List<List<Int>> = LinkedList<List<Int>>()
The intelliJ idea gives no warnings for the above declaration but add() is not available on result variable. Please let me know what I am doing wrong.
How should I initialize empty List<List<Int>> type in kotlin?
add is not available for List. It's available for MutableList. LinkedList is a MutableList, but you are upcasting it to a plain List by assigning it to a variable of type List.
If you need to work with a MutableList or LinkedList inside this function, you can do so by not declaring the type of the result variable so it will implicitly be a MutableList or LinkedList. When you return it from the function, it will be implicitly upcast at that time, when you no longer need the mutable features.
fun threeSum(nums: IntArray): List<List<Int>> {
val output = mutableListOf<MutableList<Int>>()
// logic
return output
}
or
fun threeSum(nums: IntArray): List<List<Int>> {
val output = LinkedList<LinkedList<Int>>()
// logic
return output
}
LinkedList is a specific type of MutableList that compared to the default MutableList (ArrayList) is heavier and slower at accessing specific elements in the middle, but faster at accessing elements at the start/end and faster at inserting or removing elements. You will most commonly just want to use mutableListOf to instantiate mutable lists.
you can use
var result: List<List<Int>> = listOf(listOf())
or
var result = listOf(listOf<Int>())
I tried these in Kotlin REPL
var listA = listOf(null ,null)
var listB = [null, null]
The first line works fine as expected. On displaying listA I get:
[null, null]
The second line throws the following error:
error: cannot use 'Nothing?' as reified type parameter
var listB = [null,null]
^
error: unsupported [Collection literals outside of annotations]
var listB = [null,null]
^
error: unsupported [Array<Nothing> in return type is illegal]
var listB = [null,null]
^
When I try the same with non null types,
i.e.
var listC = [1,2]
I get this error:
error: unsupported [Collection literals outside of annotations]
var listC = [1,2]
^
I'm new to Kotlin. Can someone please explain what is going on here?
From the Kotlin documentation on Collections:
Kotlin does not have dedicated syntax constructs for creating lists or sets. Use methods from the standard library, such as listOf(), mutableListOf(), setOf(), mutableSetOf().
There are no list literals currently for code outside of annotations.
As #Carcigenicate pointed out, there is not syntax for [null, null].
However, Kotlin does have some handy methods for handling lists and arrays.
Lists
listOf()
Creates a new read-only List.
listOfNotNull()
Basically the same as listOf(), but without null values. Even empty strings
are skipped.
arrayListOf()
Creates an ArrayList. This time you can modify (add/remove) elements.
mutableListOf()
Behaves like arrayListOf(). Actually, mutableListOf() internally uses ArrayLists. Read more
Arrays
arrayOf()
This creates an array, which is very different to most languages you know.
Instead of syntax structures like {1, 2, 3} or [1, 2, 3] you have functions
in Kotlin. You also get functions for typed array:
booleanArrayOf()
doubleArrayOf()
charArrayOf()
...
One exception are annotations, which explains your compiler error [Collection literals outside of annotations]:
#MyAnnotation(arguments = [1, 2, 3])
However, this could change in the future as discussed here.
While working with arrays, it is important to know the return types those functions are creating.
As an example:
Array<Int> is an Integer[] under the hood, while IntArray is a primitive int[] when targeting the JVM.
So for the case of mutable lists, you can declare an empty String one with: val list: MutableList<String> = mutableListOf(). If you wanted an immutable list then you could use val like so: val list: List<String> = listOf("x", "y", "z").
Also note, that you should consider your use case for using val or var. Mutability of a list pertains to values within the list itself, where as val and var are for the variable. You can reassign the list if you use var but not val (similar to final of Java)
For the sake of clarity, as an example, mutable lists can have elements added an removed after their initialisation, while immutable cannot.
Immutable Lists Docs
Mutable List Docs
You get [null, null] because that's how toString() happens to be defined in java.util.AbstractCollection and listOf creates a java.util.ArrayList which inherits this implementation.
The errors you get are because there is a place in Kotlin where this syntax happens to work: annotation parameters. So the parser understands it. But it creates arrays, not lists, and so your code wouldn't compile even if the syntax wasn't limited to annotations.
Yes this is not the correct syntax for creating List with Kotlin.
Here is an example of List and MutableList(with write operations) and some of the operations you can do on them:
List
val numbers = listOf("one", "two", "three", "four")
println("Number of elements: ${numbers.size}")
println("Third element: ${numbers.get(2)}")
println("Fourth element: ${numbers[3]}")
println("Index of element \"two\" ${numbers.indexOf("two")}")
MutableList
val numbers = mutableListOf(1, 2, 3, 4)
numbers.add(5)
numbers.removeAt(1)
numbers[0] = 0
numbers.shuffle()
println(numbers)
How do I convert a Map<key,value> to a List<value>? Should I iterate over all map values and insert them into a list?
List<Value> list = new ArrayList<Value>(map.values());
assuming:
Map<Key,Value> map;
The issue here is that Map has two values (a key and value), while a List only has one value (an element).
Therefore, the best that can be done is to either get a List of the keys or the values. (Unless we make a wrapper to hold on to the key/value pair).
Say we have a Map:
Map<String, String> m = new HashMap<String, String>();
m.put("Hello", "World");
m.put("Apple", "3.14");
m.put("Another", "Element");
The keys as a List can be obtained by creating a new ArrayList from a Set returned by the Map.keySet method:
List<String> list = new ArrayList<String>(m.keySet());
While the values as a List can be obtained creating a new ArrayList from a Collection returned by the Map.values method:
List<String> list = new ArrayList<String>(m.values());
The result of getting the List of keys:
Apple
Another
Hello
The result of getting the List of values:
3.14
Element
World
Using the Java 8 Streams API.
List<Value> values = map.values().stream().collect(Collectors.toList());
map.entrySet() gives you a collection of Map.Entry objects containing both key and value. you can then transform this into any collection object you like, such as new ArrayList(map.entrySet());
a list of what ?
Assuming map is your instance of Map
map.values() will return a Collection containing all of the map's values.
map.keySet() will return a Set containing all of the map's keys.
I guess you want to convert the values contained in the Map to a list? Easiest is to call the values() method of the Map interface. This will return the Collection of value objects contained in the Map.
Note that this Collection is backed by the Map object and any changes to the Map object will reflect here. So if you want a separate copy not bound to your Map object, simply create a new List object like an ArrayList passing the value Collection as below.
ArrayList<String> list = new ArrayList<String>(map.values());
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("java", 20);
map.put("C++", 45);
Set <Entry<String, Integer>> set = map.entrySet();
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
we can have both key and value pair in list.Also can get key and value using Map.Entry by iterating over list.
If you want to ensure the values in the resultant List<Value> are in the key-ordering of the input Map<Key, Value>, you need to "go via" SortedMap somehow.
Either start with a concrete SortedMap implementation (Such as TreeMap) or insert your input Map into a SortedMap before converting that to List. e.g.:
Map<Key,Value> map;
List<Value> list = new ArrayList<Value>( new TreeMap<Key Value>( map ));
Otherwise you'll get whatever native ordering the Map implementation provides, which can often be something other than the natural key ordering (Try Hashtable or ConcurrentHashMap, for variety).
// you can use this
List<Value> list = new ArrayList<Value>(map.values());
// or you may use
List<Value> list = new ArrayList<Value>();
for (Map.Entry<String, String> entry : map.entrySet())
{
list.add(entry.getValue());
}
Map<String, String > map = new HapshMap<String, String>;
map.add("one","java");
map.add("two", "spring");
Set<Entry<String, String>> set = map.entrySet();
List<Entry<String, String>> list = new ArrayList<Entry<String, String>> (set);
for(Entry<String, String> entry : list) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
Here's the generic method to get values from map.
public static <T> List<T> ValueListFromMap(HashMap<String, T> map) {
List<T> thingList = new ArrayList<>();
for (Map.Entry<String, T> entry : map.entrySet()) {
thingList.add(entry.getValue());
}
return thingList;
}
public List<Object> convertMapToList(Map<Object, Object> map){
return new ArrayList<>(map.values());
}
If you want an immutable copy of the values:
List<Value> list = List.copyOf(map.values())