Introduction to Collections: Arrays are Lists in Dart

Tags

, , , , , , , , , , , , , , ,

laern-dart-the-hard-way

Learn Dart the Hard Way

This is the most common collection in every programming language: array or an “ordered group of objects”. In Dart, arrays are List objects. We will address them as ‘lists’ in our future discussion.
JavaScript array literals look like Dart lists. Here is a sample code we may consider to understand why this concept is important:

//code 2.14
main(List arguments) {
List fruitCollection = ['Mango', 'Apple', 'Jack fruit'];
print(fruitCollection[0]);
}

Consider another piece of code:

//code 2.15
main(List arguments) {
List fruitCollection = ['Mango', 'Apple', 'Jack fruit'];
var myIntegers = [1, 2, 3];
print(myIntegers[2]);
print(fruitCollection[0]);
}

What is the difference between these two code snippets? In the above code 2.14, we have explicitly mentioned that we are going to declare a collection of fruits. And we can pick any item from that collection from the key.

As we know, when in an array key is not mentioned with the value pair, it automatically infers that the key starts from 0. Therefore, the output of code 2.14 is ‘Mango’. In the second instance, Continue reading

Anonymous Functions: Lambda, Higher Order Functions, and Lexical Closures

Tags

, , , , , , , , , ,

laern-dart-the-hard-way

Learn Dart the Hard Way

Lambda, Higher-Order functions, and Lexical Closures have some similarities. In their namelessness and anonymity, these features of Dart are very interesting. Let us start with Lambda. Then we will discuss Higher-Order Functions and Closures. In reality, you will find that Lambda actually implements Higher-Order Functions.
Today I am going to talk about the Lambda only.
Next day, I will write about the other anonymous functions.
Continue reading

Python 3: Reusing With Regular Expressions

Tags

, ,

learn python the simple way

learn python the simple way

Get the book: Learn Python 3 the simple way

You have already seen how we can search and replace words in a file with the help of regular expression. Now we will try to reuse the code so that we can use them again and again. Besides, we will also try to write them in a more human readable way.
Let us first write the steps. What we want to achieve is very important before achieving something. Let us have a clear idea first and the best way is writing them down.
Continue reading

Static Variables and Methods in Dart

Tags

, , , , ,

Learn Dart the Hard Way

To implement class-wide variables and methods, we use the static keyword. Static variables are also called class variables. Let us first see a code snippet and after that, we will discuss the advantages and disadvantages of static variables and methods.

//code 7.1
// static variables and methods consume less memory
// they are lazily initialized
class Circle{
static const pi = 3.14;
static Function drawACircle(){
//from static method you cannot call a normal function
print(pi);
}
Function aNonStaticFunction(){
//from a normal function ou can call a static meethod
Circle.drawACircle();
print("This is normal function.");
}
}
main(List arguments){
var circle = Circle();
circle.aNonStaticFunction();
Circle.drawACircle();
}

And here is the output:

3.14
This is normal function.
3.14

As you see, static variables are useful for class-wide state and constants. So in the main() method we can add this line at the end:

main(List arguments){
var circle = Circle();
circle.aNonStaticFunction();
Circle.drawACircle();
print(Circle.pi);
}

And get the value of constant ‘pi’ again. Here, ‘Circle.pi’ is the class variable. And the class method is: ‘Circle.drawACircle();’. The biggest advantage of using static variables and methods is it consumes less memory. An instance variable once instantiated, consumes memory whether it is being used or not. The static variables and methods are not initialized until they are used in the program. It consumes memory when they are used.

A few things to remember:

1. From a normal function, you can call a static method.
2. From a static method, you cannot call a normal function.
3. In a static method, you cannot use the ‘this’ keyword. It is because the static methods do not operate on an instance and thus do not have access to this.

So, in the end, we can conclude that using static variables and methods depend on the context and situations. In the next part of the book, where we will build native iOS and Android mobile apps with the help of Flutter framework, you will see how and when we use static variables and methods.

Why we need Constructor in Dart

Tags

, , , , , , , ,

Learn Dart the Hard Way

The first and foremost task of constructors is the construction of objects. Whenever we try to create an object and write this line:
var fatherBear = Bear();
We actually try to arrange a spot in the memory for that object. The real work begins when we connect that spot with class properties and methods.
Using ‘constructor’ we can do that job more efficiently. Not only that, Dart allows to create more than one ‘constructor’, which is a great advantage.
Let us write our ‘Bear’ class in a new way of using constructor:

//code 3.10
class Bear {
int numberOfFish;
int hourOfSleep;
int weightGain;
Bear(this.numberOfFish, this.hourOfSleep);
int eatFish(int numberOfFish) => numberOfFish;
int sleepAfterEatingFish(int hourOfSleep) => hourOfSleep;
int weightGaining(int weightGain) => weightGain = numberOfFish * hourOfSleep;
}
main(List arguments){
var fatherBear = Bear(6, 10);
fatherBear.weightGain = fatherBear.numberOfFish * fatherBear.hourOfSleep;
print("Father bear eats ${fatherBear.eatFish(fatherBear.numberOfFish)} fishes. And he sleeps for ${fatherBear.sleepAfterEatingFish(fatherBear.hourOfSleep)} hours.");
print("Father bear has gained ${fatherBear.weightGaining(fatherBear.weightGain)} pounds of weight.");
}

Creating ‘constructor’ is extremely easy. Watch this line:

Bear(this.numberOfFish, this.hourOfSleep);

The same class name works as a function or method and we have passed two arguments through that method. Once we get those values, we would calculate the third variable. Writing constructor this way is known as “Syntactic Sugar”. In the later section of the book we will know more about the constructor.
Now it gets easier to pass the two values while creating the object. We could have done the same by creating constructor this way, which is more traditional:

//code 3.11
class Bear {
int numberOfFish;
int hourOfSleep;
int weightGain;
Bear(int numOfFish, int hourOfSleep){
this.numberOfFish = numOfFish;
this.hourOfSleep = hourOfSleep;
}
//Bear(this.numberOfFish, this.hourOfSleep);
int eatFish(int numberOfFish) => numberOfFish;
int sleepAfterEatingFish(int hourOfSleep) => hourOfSleep;
int weightGaining(int weightGain) => weightGain = numberOfFish * hourOfSleep;
}
main(List arguments){
var fatherBear = Bear(6, 10);
fatherBear.weightGain = fatherBear.numberOfFish * fatherBear.hourOfSleep;
print("Father bear eats ${fatherBear.eatFish(fatherBear.numberOfFish)} fishes. And he sleeps for ${fatherBear.sleepAfterEatingFish(fatherBear.hourOfSleep)} hours.");
print("Father bear has gained ${fatherBear.weightGaining(fatherBear.weightGain)} pounds of weight.");
}

In both cases, the output is same as before:

//output of code 3.11
Father bear eats 6 fishes. And he sleeps for 10 hours.
Father bear has gained 60 pounds of weight.

In the above code, you can even get the object’s type very easily. We can change the type of value quite easily. Watch the main() function again:

//code 3.12
main(List arguments){
var fatherBear = Bear(6, 10);
fatherBear.weightGain = fatherBear.numberOfFish * fatherBear.hourOfSleep;
print("Father bear eats ${fatherBear.eatFish(fatherBear.numberOfFish)} fishes. And he sleeps for ${fatherBear.sleepAfterEatingFish(fatherBear.hourOfSleep)} hours.");
print("Father bear has gained ${fatherBear.weightGaining(fatherBear.weightGain)} pounds of weight.");
print("The type of the object : ${fatherBear.weightGain.runtimeType}");
String weightGained = fatherBear.weightGain.toString();
print("The type of the same object has changed to : ${weightGained.runtimeType}");
}

And here is the output:

//output of code 3.12
Father bear eats 6 fishes. And he sleeps for 10 hours.
Father bear has gained 60 pounds of weight.
The type of the object : int
The type of the same object has changed to : String

How Functions or Methods Work in Dart

Tags

, , ,

How Functions or Methods Work in Dart? Here is a quick tip that can teach you the basic programming knowledge of Dart.

Learn Dart the Hard Way

We need to understand a few important features of functions before we dig deep into object-oriented programming again. The proper understanding of functions will help us to understand methods inside a class.
First of all, there are functions that just do nothing.
It called: ‘void’.
Let us consider this code:

//code 3.15
main(List arguments){
print(showConnection());
}
//optional positional parameter
String myConnection(String dbName, String hostname, String username, [String optionalPassword]){
if(optionalPassword == null){
return "${dbName}, ${hostname}, $username";
} else return "${dbName}, ${hostname}, $username, $optionalPassword";
}
void showConnection(){
myConnection("MySQL", "localhost", "root", "*******");
}

We have declared the function ‘showConnection()’ as ‘void’ and want to return it through the ‘main()’ function. We have this output:

//output of code 3.15
bin/main.dart:4:9: Error: This expression has type ‘void’ and can’t be used.
print(showConnection());

We cannot use the type ‘void’. If we use, we cannot return something through that function. So from a function we always expect something. We want a function to return a value.
So we are going to change the above code and write it this way:

//code 3.16
main(List arguments){
var myConnect = myConnection(“MySQL”, “localhost”, “root”, “*******”);
print(myConnect);
}
//optional positional parameter
String myConnection(String dbName, String hostname, String username, [String optionalPassword]){
if(optionalPassword == null){
return “${dbName}, ${hostname}, $username”;
} else return “${dbName}, ${hostname}, $username, $optionalPassword”;
}

A simple program to express the database connections parameters. In the above code, we have used a new concept called the optional parameter. You have already known that if we declare parameters or arguments in our functions, we have to pass them as it is. Otherwise, it gives us errors. However, we can use the concept of ‘optional parameters’. In the function ‘myConnections()’ we have passed four arguments.

Watch this line:

String myConnection(String dbName, String hostname, String username, [String optionalPassword]){}

We have written the last argument as [String optionalPassword]. It means this argument is optional. You do not have to pass it when you call the function. Here the logic is simple. If the optional parameter ‘optionalPassword’ is not defined when we pass it inside the ‘main()’ function, it is treated as ‘null’. Since it has been defined and passed it afterward, it is not null. Therefore, we have got this output:

//output of code 3.16
MySQL, localhost, root, *******

Now, we change the above code slightly and will not pass that argument anymore.
//code 3.17
main(List arguments){
var myConnect = myConnection("MySQL", "localhost", "root");
print(myConnect);
}
//optional positional parameter
String myConnection(String dbName, String hostname, String username, [String optionalPassword]){
if(optionalPassword == null){
return "${dbName}, ${hostname}, $username";
} else return "${dbName}, ${hostname}, $username, $optionalPassword";
}
The output also changes:
//output of code 3.17
MySQL, localhost, root

Compare these two lines before and after and we will only then understand why optional parameter is important:

//code 3.16
var myConnect = myConnection("MySQL", "localhost", "root", "*******");
//code 3.17
var myConnect = myConnection("MySQL", "localhost", "root");

If we did not declare it as optional, it would have given us an error. Let us change the optional parameter and see what type of error we get.

//code 3.18
main(List arguments){
var myConnect = myConnection("MySQL", "localhost", "root");
print(myConnect);
}
//optional positional parameter is no more
String myConnection(String dbName, String hostname, String username, String optionalPassword){
if(optionalPassword == null){
return "${dbName}, ${hostname}, $username";
} else return "${dbName}, ${hostname}, $username, $optionalPassword";
}
Now optional parameter is no more, and for that reason, we encounter this error in the output:
//output of code 3.18
bin/main.dart:3:31: Error: Too few positional arguments: 4 required, 3 given.
var myConnect = myConnection("MySQL", "localhost", "root");
^
bin/main.dart:8:8: Context: Found this candidate, but the arguments don't match.
String myConnection(String dbName, String hostname, String username, String optionalPassword){

Since there was no optional parameter we had to pass the fourth argument. In the previous code snippets, we did not have to do that.
Since in Dart, a function is an object, the same concept is true in case of methods and you will find it when we will discuss object-oriented programming again.

Anonymous Functions: Lambda, Higher Order Functions, and Lexical Closures

Tags

, , , , , ,

I teach computer science and programming languages, such as C, C++, C#, Python, PHP, Java, and Dart; you may also learn PHP framework like Laravel. Just drop me a message either at my email or Skype.

E-mail - sanjib12sinha@gmail.com
Skype ID - live:sanjib12sinha

Learn Dart the Hard Way

In this article we will take a look at some special functions in Dart programming language – Anonymous Functions: Lambda, Higher Order Functions, and Lexical Closures
Lambda, Higher Order functions, and Lexical Closures have some similarities. In their namelessness and anonymity, these features of Dart are very interesting. Let us first start with Lambda. Then we will discuss Higher Order functions and Closures. In reality, you will find that Lambda actually implements Higher Order Functions.
Lambda: The Anonymous Function
As the name suggests, Lambda is a nameless function and we can use it in two ways. We can use it in a traditional method and also we can use the ‘Fat Arrow’.
Consider the first code snippet:
//code 8.1
class LambdaCode{
// here addingTwonumbers is a nameless function
Function addingTwonumbers = (int x, int y){
var sum = x + y;
return sum;
};
}
main(List arguments){
var lambdaShow = LambdaCode();
print(lambdaShow.addingTwonumbers(12, 47));
}

I will give the output after adding the ‘Fat Arrow’ method. The whole code snippet looks like this:
//code 8.2
class LambdaCode{
// here addingTwonumbers is a nameless function
Function addingTwonumbers = (int x, int y){
var sum = x + y;
return sum;
};
Function divideByFour = (int num) => num ~/ 4;
}
main(List arguments){
var lambdaShow = LambdaCode();
print(lambdaShow.addingTwonumbers(12, 47));
print(lambdaShow.divideByFour(56));
}

The output is quite expected, in the first anonymous function ‘Function addingTwonumbers’ we have passed two parameters and added them. And using the ‘Fat Arrow’ method, we have passed a number through another nameless function ‘Function divideByFour’ and divided it by 4.
//output of code 8.2
59
14

While building a native iOS or Android app, you will see how these nameless functions come to your help.

Exploring Higher Order Functions

The specialty of Higher Order functions is it can accept a function as a parameter. That is why it is named Higher Order Function. It not only can accept a function as a parameter, but it can also return it; actually, it can do both.
We will see a very simple code snippet to get accustomed to the idea.
//code 8.3
//returning a function
Function DividingByFour(){
Function LetUsDivide = (int x) => x ~/ 4;
return LetUsDivide;
}
main(List arguments){
var result = DividingByFour();
print(result(56));
}

The output is 14.
So we have passed a nameless function ‘Function LetUsDivide’ as a parameter and returned the function quite easily through a higher order function ‘Function DividingByFour()’.
The closure is a Special Function
We can define Closure in two ways. According to the first definition, we can say that Closure is the only function that has access to the parent scope, even after the scope is closed.
To understand this definition, let us see a very short code snippet:
//code 8.4
//a closure can modify the parent scope
String message = "Any Parent String";
Function overridingParentScope = (){
String message = "Overriding the parent scope";
print(message);
};
main(List arguments){
print(message);
overridingParentScope();
}
The output is:
Any Parent String
Overriding the parent scope

By the second definition, we can say that a Closure is a function object that has access to the variables in its lexical scope, even when the function is used outside of its original scope.
//code 8.5
Function show = (){
String pathToImage = "This is an old path.";
Function gettingImage(){
String path = "This is a new path to image.";
print(path);
}
return gettingImage;
};
main(List arguments){
var showing = show();
showing();
}
Here is the output: This is a new path to image.

It actually returns a function object ‘gettingImage’ that has accessed the variable in its lexical scope.

So at the end of this section, we can summarize the points about Closure.
1. In several other languages, you are not allowed to modify the parent variable.
2. However, within a closure, you can mutate or modify the values of variables present in the parent scope.
3. All together, Closure is a very special type of function.

Now we will conclude our whole journey to study the nameless functions in one single code base, and we will also see the output.
//code 8.6
//Lambda is an anonymous function
class AboutLambdas{
//first way of expressing Lambda or anonymous function
Function addingNumbers = (int a, int b){
var sum = a + b;
//print(sum);
return sum;
};
Function multiplyWithEight = (int num){
return num * 8;
};
//second way of expressing Lambda by Fat Arrow
Function showName = (String name) => name;
//higher order functions pass function as parameter
int higherOrderFunction(Function myFunction){
int a = 10;
int b = 20;
print(myFunction(a, b));
}
//returning a function
Function returningAFunction(){
Function showAge = (int age) => age;
return showAge;
}
//a closure can modify the parent scope
String anyString = "Any Parent String";
Function overridingParentScope = (){
String message = "Overriding the parent scope";
print(message);
};
Function show = (){
String pathToImage = "This is an old path.";
Function gettingImage(){
String path = "This is a new path to image.";
print(path);
}
return gettingImage;
};
}
main(List arguments){
var add = AboutLambdas();
var addition = add.addingNumbers(5, 10);
print(addition);
var mul = AboutLambdas();
var result = mul.multiplyWithEight(4);
print(result);
var name = AboutLambdas();
var myName = name.showName("Sanjib");
print(myName);
var higher = AboutLambdas();
var higherOrder = higher.higherOrderFunction(add.addingNumbers);
higherOrder;
var showAge = AboutLambdas();
var showingAge = showAge.returningAFunction();
print(showingAge(25));
var sayMessage = AboutLambdas();
sayMessage.overridingParentScope();
var image = AboutLambdas();
var imagePath = image.show();
imagePath();
}

And in the output we will see how the nameless functions work in different ways.
//output of code 8.6
15
32
Sanjib
30
25
Overriding the parent scope
This is a new path to image.

Static Variables and Methods in Dart Programming

Tags

, , , , , , ,

laern-dart-the-hard-way

https://leanpub.com/learndartthehardway

To implement class-wide variables and methods, we use the static keyword. Static variables are also called class variables. Let us first see a code snippet and after that we will discuss the advantages and disadvantages of static variables and methods.
//code 7.1
// static variables and methods consume less memory
// they are lazily initialized
class Circle{
static const pi = 3.14;
static Function drawACircle(){
//from static method you cannot call a normal function
print(pi);
}
Function aNonStaticFunction(){
//from a normal function ou can call a static meethod
Circle.drawACircle();
print("This is normal function.");
}
}
main(List arguments){
var circle = Circle();
circle.aNonStaticFunction();
Circle.drawACircle();
}

And here is the output:
3.14
This is normal function.
3.14

As you see, static variables are useful for class-wide state and constants. So in the main() method we can add this line at the end:
main(List arguments){
var circle = Circle();
circle.aNonStaticFunction();
Circle.drawACircle();
print(Circle.pi);
}

And get the value of constant ‘pi’ again. Here, ‘Circle.pi’ is the class variable. And the class method is: ‘Circle.drawACircle();’. The biggest advantage of using static variables and methods is it consumes less memory. An instance variable once instantiated, consumes memory whether it is being used or not. The static variables and methods are not initialized until they are used in the program. It consumes memory when they are used.
A few things to remember:

1. From a normal function you can call a static method.
2. From a static method, you cannot call a normal function.
3. In a static method you cannot use the ‘this’ keyword. It is because the static methods do not operate on an instance and thus do not have access to this.

So at the end we can conclude that using static variables and methods depend on the context and situations. In the next part of the book, where we will build native iOS and Android mobile apps with the help of Flutter framework, you will see how and when we use static variables and methods.

Maps: the Key, Value Pair in Dart Programming Language

Tags

, , , , ,

laern-dart-the-hard-way

https://leanpub.com/learndartthehardway

An unordered collection of Key-Value pair is known as Map in Dart. The main advantage of Map is the Key-Value pair can be of any type.
To begin with, let us start with some points that we should remember while working with Map.

1. Each Key in a Map should be unique.
2. The value can be repeated.
3. The Map can commonly be called hash or dictionary.
4. Size of a Map is not fixed, it can either increase or decrease as per the number of elements. In other words, Maps can grow or shrink at runtime.
5. HashMap is an implementation of a Map and it is based on a Hash table.

Let us see a code snippet to understand how a Map works in Dart.
//code 9.4
void mapFunction(){
//unordered collection of key=>value pair
Map countries = Map();
countries['India'] = "Asia";
countries["German"] = "Europe";
countries["France"] = "Europe";
countries["Brazil"] = "South America";
//1. method we can obtain key or value
for(var key in countries.keys){
print("Countries' name: $key");
}
print("-----------");
for(String value in countries.values){
print("Continents' name: $value");
}
//2. method
countries.forEach((key, value) => print("Country: $key and Continent: $value"));
//we can update any map very easily
if(countries.containsKey("German")){
countries.update("German", (value) => "European Union");
print("Updated country German.");
countries.forEach((key, value) => print("Country: $key and Continent: $value"));
}
//we can remove any country
countries.remove("Brazil");
countries.forEach((key, value) => print("Country: $key and Continent: $value"));
print("Barzil has been removed successfully.");
print("-----------");
//3. method of creating a map
Map telephoneNumbersOfCustomers = {
"John" : 1234,
"Mac" : 7534,
"Molly" : 8934,
"Plywod" : 1275,
"Hagudu" : 2534
};
telephoneNumbersOfCustomers.forEach((key, value) => print("Customer: $key and Contact NUmber: $value"));
}
main(List arguments){
mapFunction();
}

And here is the output of code 9.4
Countries' name: India
Countries' name: German
Countries' name: France
Countries' name: Brazil
-----------
Continents' name: Asia
Continents' name: Europe
Continents' name: Europe
Continents' name: South America
Country: India and Continent: Asia
Country: German and Continent: Europe
Country: France and Continent: Europe
Country: Brazil and Continent: South America
Updated country German.
Country: India and Continent: Asia
Country: German and Continent: European Union
Country: France and Continent: Europe
Country: Brazil and Continent: South America
Country: India and Continent: Asia
Country: German and Continent: European Union
Country: France and Continent: Europe
Barzil has been removed successfully.
-----------
Customer: John and Contact NUmber: 1234
Customer: Mac and Contact NUmber: 7534
Customer: Molly and Contact NUmber: 8934
Customer: Plywod and Contact NUmber: 1275
Customer: Hagudu and Contact NUmber: 2534

There are three methods that we use to retrieve the values of a Map.
//1. method we can obtain key or value
for(var key in countries.keys){
print("Countries' name: $key");
}
print("-----------");
//2. Method
for(String value in countries.values){
print("Continents' name: $value");
}
//3. method
countries.forEach((key, value) => print("Country: $key and Continent: $value"));

Besides, there are several methods to add, update or remove the elements in a Map. As we progress and build apps in native iOS or Android, we will see more features of Map. Lastly we will see another collection feature in Map, which is called Queue.

List, Set and Map : Data structures in Dart

Tags

, , , , ,

laern-dart-the-hard-way

https://leanpub.com/learndartthehardway

In Dart, a Set is an unordered collection of unique items. There are small difference in syntaxes between List and Set.
Let us see an example first to know more about the difference.
//code 2.18
main(List arguments) {
var fruitCollection = {'Mango', 'Apple', 'Jack fruit'};
print(fruitCollection.lookup('Apple'));
}
//output of code 2.18
Apple

We can search the Set using the lookup() method. If we search something else, it returns ‘null’.
//code 2.19
main(List arguments) {
var fruitCollection = {'Mango', 'Apple', 'Jack fruit'};
print(fruitCollection.lookup('Something Else'));
}
//output of code 2.19
null

Remember one key point regarding Set and Map. When we write:
var myInteger = {};
It does not create a Set, but a Map. The syntax for map literals is similar to that of for set literals. Why does it happen? Because map literals came first, the literal {} is a default to the Map type. We can prove this by a simple test:
//code 2.20
main(List arguments) {
var myInteger = {};
if(myInteger.isEmpty){
print("It is a map that has no key, value pair.");
} else print("It is a set that has no key, value pair.");
}
Watch the output:
//output of code 2.20
It is a map that has no key, value pair.

It means the map is empty. If it was a set, we would have got the output in that direction. We will see lots of examples of Sets in future, while we build our mobile application. At present just remember, in general, a map is an object that associates keys and values. The set has also keys, but that are implicit. In cases of Sets, we call it indexes.
Let us see one example of Map type by map literals. While writing keys and values, it is important to note that each key occurs only once, but you can use the same value many times.
//code 2.21
main(List arguments) {
var myProducts = {
'first' : 'TV',
'second' : 'Refrigerator',
'third' : 'Mobile',
'fourth' : 'Tablet',
'fifth' : 'Computer'
};
print(myProducts['third']);
}

The output is obvious : ‘Mobile’. Dart understands that the ‘myProducts’ has the type Map(Map); we could have made the key integers or number type, instead of a string type.
//code 2.22
main(List arguments) {
var myProducts = {
1 : 'TV',
2 : 'Refrigerator',
3 : 'Mobile',
4 : 'Tablet',
5 : 'Computer'
};
print(myProducts[3]);
}

The output is the same as before – mobile.
Can we add a Set type collection of value inside a Map? Yes, we can. Consider this code:
//code 2.23
main(List arguments) {
Set mySet = {1, 2, 3};
var myProducts = {
1 : 'TV',
2 : 'Refrigerator',
3 : mySet.lookup(2),
4 : 'Tablet',
5 : 'Computer'
};
print(myProducts[3]);
}

In the above code (2.23) we have injected a collection of Set type and we also have looked up for the defining value through the Map key. Here, inside the Map key, value pair we have added the set element number 2, this way: 3 : mySet.lookup(2), and later we have told our Android Studio editor to display the value of the Map type ‘myProducts’ .
The output is quite expected: 2.
You can create the same products lists by Map constructor. For the beginners, the term “constructor” might seem difficult. We will discuss this term in detail in our object-oriented programming category. Consider this code:
//code 2.24
main(List arguments) {
var myProducts = Map();
myProducts['first'] ='TV';
myProducts['second'] ='Mobile';
myProducts['third'] ='Refrigerator';
if(myProducts.containsValue('Mobile')){
print("Our products’ list has ${myProducts['second']}");
}
}

And here is the output:
//output of code 2.24
Our products’ list has Mobile
Since we have had an instance (in code 2.24) of Map class, the seasoned programmer might have expected ‘new Map()’ instead of only ‘Map()’.
As of Dart 2, the new keyword is optional. We will learn about these, in detail, in the coming object-oriented programming chapter.
We will also have a separate “Collections” chapter later, where we will learn more about List, Set and Map.