Why List [T] and not List [Int]? What does T mean?

In all examples, I am ready that such a definition of a function continues to appear:

def firstElementInList[T](l: List[T]): T 

I'm used to seeing List[Int] , so this will be a list of integers. In this case, I assume that T is any type (please correct me if I am wrong). What I really get is [T] right after firstElementInList

+4
source share
3 answers

This is just a way of saying: this function refers to one common type T (you are right T is any type).

If you have multiple methods inside the same class:

 def firstElementInList[T](l: List[T]): T = l.head def lastElementInList[T](l: List[T]): T = l.last 

then each method has its own type T , so you can call the first method with the String list, and the second with the Int s list.

However, an entire class containing both of these methods can be of type:

 class Foo[T] { def firstElementInList(l: List[T]): T = l.head def lastElementInList(l: List[T]): T = l.last } 

In this case, you select the type when creating the Foo object:

 val foo = new Foo[String] 

and the compiler will not allow you to call Foo instance methods with any type other than List[String] . Also note that in this case you no longer need the type [T] for the method - it is taken from the surrounding class.

+8
source

T is a "unrelated" type. In other words, List<T> is short for "list of things."

This means that you can use the same code to make the "list of people" a "list of dates" or a "list of accounts", you just provide a constructor

 List<Person> people = new List<Person>(); 

which will tie T to people. Now that you are accessing the List , this ensures that a previously unrelated T existed everywhere, it will act as if it were written with People in that position. For example, public T remove(int) will return T , which is tied to People in the list of people. This avoids the need to add explicit casts. It also ensures that the only elements in the List are at least People.

 List<Person> people = new List<Person>(); // T is bound to "People" List<Account> accounts = new List<Account>(); // T is bound to "Account" Person first = people.remove(0); Account firstAccount = accounts.remove(0); // The following line fails because Java doesn't automatically cast (amongst classes) Account other = people.remove(0); // as people is a List<T> where T is bound to "People", people.remove(0) will return // a T which is bound to People. In short it will return something that is at least an // instance of People. This doesn't cast into an account (even though there are other // lists which would). 

Note that at least People’s comment is an indicator that a list can contain multiple objects, but all objects must be subclassed by People.

+2
source

This is the parameterization of the function: your guess was correct: if you pass List of Ints , this function should return Int , if you pass List from Strings , the return value should be String , etc. In addition, you can use this type in the function area, for example. eg:

 def foo[T](l: List[T]): T = { ... val z = collections.mutable.HashMap[String,T] ... } 
+1
source

Source: https://habr.com/ru/post/1383962/


All Articles