Data Structures and Null Safety in Dart - Part 4

Data Structures and Null Safety in Dart - Part 4

Exploring Data Structures and Null Safety - Lists, Maps, Maps and Null Safety in Dart

Dart, as a modern programming language, offers robust support for data structures like lists, maps, and sets, along with features such as null safety for writing more secure and predictable code. In this blog post, we'll delve into the basics of these data structures and explore how Dart's null safety features enhance code reliability.

1. Lists Lists in Dart are ordered collections of objects. They are dynamic and can grow or shrink in size. Let's explore some basic operations with lists:

void main() {
  // Create a list of integers named 'marks' with initial values.
  List<int> marks = [34, 78, 87, 97, 105];

  // Add an element '107' to the end of the 'marks' list.
  marks.add(107);

  // Remove the element '105' from the 'marks' list.
  marks.remove(105);

  // Insert the element '30' at index 0 of the 'marks' list.
  marks.insert(0, 30);

  // Output the entire list of 'marks'.
  print(marks);

  // Output the length of the 'marks' list.
  print("Length is ${marks.length}");

  // Output the first element of the 'marks' list.
  print("First Index is ${marks[0]}");

  // Output the last element of the 'marks' list.
  print("Last Index is ${marks[4]}");

  // Join all elements of the 'marks' list into a single string separated by spaces.
  final join = marks.join(" ");
  print("Joined method $join");

  // Create a string named 'name' with the value "Flutter".
  String name = "Flutter";

  // Split the 'name' string into a list of substrings based on spaces.
  final split = name.split(" ");
  print("Split method $split");
}

Here's what each part does:

  • List marks = [34, 78, 87, 97, 105];: Initializes a list named 'marks' with integers [34, 78, 87, 97, 105].

  • marks.add(107);: Appends the integer 107 to the end of the 'marks' list.

  • marks.remove(105);: Removes the integer 105 from the 'marks' list.

  • marks.insert(0, 30);: Inserts the integer 30 at the beginning (index 0) of the 'marks' list.

  • print(marks);: Outputs the entire list of 'marks'.

  • print("Length is ${marks.length}");: Outputs the length of the 'marks' list.

  • print("First Index is ${marks[0]}");: Outputs the first element of the 'marks' list.

  • print("Last Index is ${marks[4]}");: Outputs the last element of the 'marks' list.

  • final join = marks.join(" ");: Joins all elements of the 'marks' list into a single string separated by spaces.

  • final split = name.split(" ");: Splits the string 'name' into a list of substrings based on spaces.

2. Maps Maps in Dart represent collections of key-value pairs. They are unordered collections, but the keys are unique within a map. Here's how we can work with maps:

void main() {
  // Create a map named 'person' with string keys and dynamic values.
  Map<String, dynamic> person = {
    'name': 'sadanand',
    'age': 23,
    'city': "kalaburagi",
  };

  // Access and print values from the 'person' map using keys.
  print(person['name']); // Prints the value associated with the key 'name'.
  print(person['age']);  // Prints the value associated with the key 'age'.
  print(person['city']); // Prints the value associated with the key 'city'.

  // Add a new key-value pair 'phone' to the 'person' map.
  person['phone'] = "91-7204832431";

  // Output all values of the 'person' map in a single line.
  print(person.values);
}

Here's what each part does:

  • Map<String, dynamic> person = {...};: Initializes a map named 'person' with string keys and dynamic values. It contains information about a person's name, age, and city.

  • print(person['name']);, print(person['age']);, print(person['city']);: Accesses and prints the values associated with the keys 'name', 'age', and 'city' respectively from the 'person' map.

  • person['phone'] = "91-7204832431";: Adds a new key-value pair 'phone' with the value "91-7204832431" to the 'person' map.

  • print(person.values);: Prints all the values stored in the 'person' map in a single line. The values are retrieved as an iterable using the values property of the map.

3. Sets Sets in Dart are collections of unique items. They do not allow duplicate elements. Let's see how sets work:

void main() {
  // Create a set named 'numbers' with integer elements.
  Set<int> numbers = {0,10, 20, 30, 40, 50};

  // Output the entire set 'numbers'.
  print(numbers);

  // Create a list named 'marks' with integer elements, including duplicates.
  List<int> marks = [1,34, 78, 78, 87, 97, 105, 105];

  // Create a set named 'uniqueSet' by removing duplicate elements from the 'marks' list.
  final uniqueSet = Set.of(marks);
  print(uniqueSet); // Output the unique elements set.

  // Create a new list named 'notUniqueList' by copying elements from the 'marks' list.
  final notUniqueList = List.from(marks);
  print(notUniqueList); // Output the copied list.

  // Iterate over the 'marks' list using a for loop with index.
  print("Printing marks list using a for loop");
  for (int i = 0; i < marks.length; i++) {
    print(marks[i]);
  }

  // Iterate over the 'marks' list to get every item using a for-in loop.
  print("Printing marks list to get every item");
  for (int mark in marks) {
    print(mark);
  }
}

Here's what each part does:

  • Set numbers = {0,10, 20, 30, 40, 50};: Initializes a set named 'numbers' containing integer elements.

  • print(numbers);: Outputs the entire set of 'numbers'.

  • List marks = [1,34, 78, 78, 87, 97, 105, 105];: Initializes a list named 'marks' with integer elements, including duplicates.

  • final uniqueSet = Set.of(marks);: Creates a set named 'uniqueSet' by removing duplicate elements from the 'marks' list.

  • print(uniqueSet);: Outputs the unique elements in the set 'uniqueSet'.

  • final notUniqueList = List.from(marks);: Creates a new list named 'notUniqueList' by copying elements from the 'marks' list.

  • print(notUniqueList);: Outputs the copied list 'notUniqueList'.

  • Iterating over the 'marks' list using both a traditional for loop and a for-in loop, printing each element in separate sections.

4. Null Safety in Dart Dart provides null safety features to prevent null reference errors, which are common in many programming languages. Here's how null safety works:

void main() {
  // Non-nullable variable (will cause an error if used before initialized)
  int x;
  print(x); // This line will cause an error because 'x' is not initialized.

  // Nullable variable
  int? y;
  print(y); // This will print 'null' because 'y' is nullable and not initialized.

  int? z = 10; // Nullable variable with an initial value

  // Using if-else statement for null check
  if(z == null) {
    print("null");
  } else {
    print(z.isEven); // Checks if 'z' is even if it's not null.
  }

  // Null safety operator for concise null checks
  print(z?.isEven); // Prints whether 'z' is even if 'z' is not null. Otherwise, prints null.

  // Null assertion operator (!) for asserting that a value is not null
  print(z!.isEven); // Asserts that 'z' is not null and prints whether 'z' is even.
}

Explanation for Null safety:

  • Dart introduced null safety to prevent null reference errors. Variables can be non-nullable or nullable.

  • Non-nullable variables must be initialized before use, otherwise, it will cause a compilation error.

  • Nullable variables are denoted with a question mark ?. They can hold either a value of their type or null.

  • The ?. operator (null safety operator) allows concise null checks. It returns null if the object is null, otherwise, it accesses the property or calls the method.

  • The ! operator (null assertion operator) asserts that the operand is non-null. It's useful when the programmer knows that the value isn't null and wants to access it directly without a null check. However, if the value is null, it will cause a runtime error.

Conclusion Understanding these fundamental data structures and null safety features is crucial for writing efficient and reliable Dart code. Incorporating them into your projects can significantly improve code readability, maintainability, and robustness.

Did you find this article valuable?

Support Sadanand gadwal by becoming a sponsor. Any amount is appreciated!