List literals

A List is an important data structure in Scala. It is very similar to an Array, but a List is immutable and, like a List in Java, its underlying implementation is a linked List.

scala>  val list = List("hadoop"."spark"."storm")
list: List[String] = List(hadoop, spark, storm)

// List is immutable
scala> list(1) = "hive"
<console>:9: error: value update is not a member of List[String]
Copy the code

Second, List type

Lists in Scala have the following two features:

  • Homogeneous: All elements in a List must be of the same type;
  • Covariance (covariant)If S is a subtype of T, thenList[S]isList[T]Subtype of, for exampleList[String]List[Object]Subtype of.

Note that the empty List is of type List[Nothing] :

scala> List()
res1: List[Nothing] = List()
Copy the code

Build a List

All lists are made up of two basic units: Nil and :(pronounced “cons”). That is, a List is either Nil or consists of a head plus a tail, which in turn is a List. The List we used above (“hadoop”, “spark”, “storm”) is also ultimately interpreted as “hadoop”::”spark”:: “storm”::Nil.

scala>  val list01 = "hadoop": :"spark": :"storm"::Nil
list01: List[String] = List(hadoop, spark, storm)

// the :: operation symbol is right associative, so the expression above is equivalent to the expression below
scala> val list02 = "hadoop": : ("spark": : ("storm"::Nil))
list02: List[String] = List(hadoop, spark, storm)
Copy the code

4. Pattern matching

Scala supports expanding lists for pattern matching.

scala>  val list = List("hadoop"."spark"."storm")
list: List[String] = List(hadoop, spark, storm)

scala> val List(a,b,c)=list
a: String = hadoop
b: String = spark
c: String = storm
Copy the code

If only part of the content needs to be matched, you can do as follows:

scala> val a::rest=list
a: String = hadoop
rest: List[String] = List(spark, storm)
Copy the code

5. Basic operations of lists

5.1 Common Methods

object ScalaApp extends App {

  val list = List("hadoop"."spark"."storm")

  // 1. Check whether the list is empty
  list.isEmpty

  // 2. Return the first element in the list
  list.head

  // 3. Return all elements in the List except the first element.
  list.tail

  // 4. Tail and head can be used together
  list.tail.head

  // 5. Return the last element in the list as opposed to head
  list.init

  // 6. Return all elements in the List except for the last one
  list.last

  // 7. Use subscripts to access elements
  list(2)

  // 8. Get the list length
  list.length

  // reverse the list
  list.reverse

}
Copy the code

5.2 indices

The indices method returns all subscripts.

scala> list.indices
res2: scala.collection.immutable.Range = Range(0.1.2)
Copy the code

5.3 take & drop & splitAt

  • Take: get the first n elements;
  • Drop: deletes the first n elements.
  • SplitAt: The number of positions from which to split.
scala> list take 2
res3: List[String] = List(hadoop, spark)

scala> list drop 2
res4: List[String] = List(storm)

scala> list splitAt 2
res5: (List[String], List[String]) = (List(hadoop, spark),List(storm))
Copy the code

5.4 flatten

Flatten takes a list of lists and flattens it, returning a single list.

scala>  List(List(1.2), List(3), List(), List(4.5)).flatten
res6: List[Int] = List(1.2.3.4.5)
Copy the code

5.5 the zip and unzip

Zip on both lists results in the following, returning a List of tuples of the elements in their respective positions; unzip does the reverse.

scala> val list = List("hadoop"."spark"."storm")
scala> val score = List(10.20.30)

scala> val zipped=list zip score
zipped: List[(String, Int)] = List((hadoop,10), (spark,20), (storm,30))

scala> zipped.unzip
res7: (List[String], List[Int]) = (List(hadoop, spark, storm),List(10.20.30))
Copy the code

5.6 the toString & mkString

ToString returns a string representation of the List.

scala> list.toString
res8: String = List(hadoop, spark, storm)
Copy the code

If you want to change the string representation of a List, you can use mkString. MkString has three overloaded methods, defined as follows:

// start: prefix sep: separator end: suffix
def mkString(start: String, sep: String, end: String): String =
  addString(new StringBuilder(), start, sep, end).toString

// seq delimiter
def mkString(sep: String): String = mkString("", sep, "")

// If no separator is specified, "" is used by default
def mkString: String = mkString("")
Copy the code

The following is an example:

scala> list.mkString
res9: String = hadoopsparkstorm

scala>  list.mkString(",")
res10: String = hadoop,spark,storm

scala> list.mkString("{".","."}")
res11: String = {hadoop,spark,storm}
Copy the code

5.7 iterator & toArray & copyToArray

The iterator method returns iterators, just as it does in other languages.

object ScalaApp extends App {

  val list = List("hadoop"."spark"."storm")

  val iterator: Iterator[String] = list.iterator

  while (iterator.hasNext) {
    println(iterator.next)
  }
  
}
Copy the code

ToArray and toList are used to convert lists and arrays to and from each other.

scala> val array = list.toArray
array: Array[String] = Array(hadoop, spark, storm)

scala> array.toList
res13: List[String] = List(hadoop, spark, storm)
Copy the code

CopyToArray copies elements of a List to the specified location in the array.

object ScalaApp extends App {

  val list = List("hadoop"."spark"."storm")
  val array = Array("10"."20"."30")

  list.copyToArray(array,1)

  println(array.toBuffer)
}

Output: ArrayBuffer(10, Hadoop, spark)
Copy the code

Advanced operations on lists

6.1 List Conversion: Map, flatMap, and foreach

A Map is similar to a Map in Java 8 functional programming in that it performs a specified operation on each element in a List.

scala> List(1.2.3).map(_+10)
res15: List[Int] = List(11.12.13)
Copy the code

A flatMap is similar to a Map, but if the elements in a List are still a List, the flatten operation is applied to them.

scala> list.map(_.toList)
res16: List[List[Char]] = List(List(h, a, d, o, o, p), List(s, p, a, r, k), List(s, t, o, r, m))

scala> list.flatMap(_.toList)
res17: List[Char] = List(h, a, d, o, o, p, s, p, a, r, k, s, t, o, r, m)
Copy the code

Foreach requires that the operation on the right be a function that returns Unit, which you can simply interpret as executing code with no return value.

scala> var sum = 0
sum: Int = 0

scala> List(1.2.3.4.5) foreach (sum += _)

scala> sum
res19: Int = 15
Copy the code

6.2 List Filtering: Filter & Partition & find & takeWhile & dropWhile & span

Filter is used to filter the elements that meet the criteria and return a new List.

scala> List(1.2.3.4.5) filter (_ % 2= =0)
res20: List[Int] = List(2.4)
Copy the code

Partition groups elements by filter criteria. The return type is tuple.

scala> List(1.2.3.4.5) partition (_ % 2= =0)
res21: (List[Int], List[Int]) = (List(2.4),List(1.3.5))
Copy the code

Find finds the first value that meets the condition. Since no such value may exist, the return type is Option. GetOrElse returns the default value if no such value exists.

scala> List(1.2.3.4.5) find (_ % 2= =0)
res22: Option[Int] = Some(2)

val result: Option[Int] = List(1.2.3.4.5) find (_ % 2= =0)
result.getOrElse(10)
Copy the code

TakeWhile iterates through the element until the first nonconforming value is encountered, and returns all iterated values.

scala> List(1.2.3, -4.5) takeWhile (_ > 0)
res23: List[Int] = List(1.2.3)
Copy the code

DropWhile iterates through the element until the first unqualified value is encountered, and returns all uniterated values.

// The first value does not satisfy the condition, so all values in the list are returned
scala> List(1.2.3, -4.5) dropWhile  (_ < 0)
res24: List[Int] = List(1.2.3, -4.5)


scala> List(1.2.3, -4.5) dropWhile (_ < 3)
res26: List[Int] = List(3, -4.5)
Copy the code

Span traverses the elements until the first unqualified value is encountered, and the traversed and untraversed values are returned in two lists. The return type is tuple.

scala> List(1.2.3, -4.5) span (_ > 0)
res27: (List[Int], List[Int]) = (List(1.2.3),List(-4.5))
Copy the code

6.3 List Check: forall & Exists

Forall checks all elements in the List and returns true if all elements meet the criteria.

scala> List(1.2.3, -4.5) forall ( _ > 0 )
res28: Boolean = false
Copy the code

Exists checks the elements in the List and returns true if an element already satisfies the condition.

scala>  List(1.2.3, -4.5) exists (_ > 0 )
res29: Boolean = true
Copy the code

6.4 List sorting: sortWith

SortWith sorts all elements in a List according to the specified rules. Since the List is immutable, sorting returns a new List.

scala> List(1, -3.4.2.6) sortWith (_ < _)
res30: List[Int] = List(-3.1.2.4.6)

scala> val list = List( "hive"."spark"."azkaban"."hadoop")
list: List[String] = List(hive, spark, azkaban, hadoop)

scala> list.sortWith(_.length>_.length)
res33: List[String] = List(azkaban, hadoop, spark, hive)
Copy the code

List object method

All of the methods described above are methods on the List class, and the following are methods on the List companion object.

7.1 the List. The range

Range can produce a List of values within the specified open and closed ranges. This List takes three optional arguments: start(start value), end(end value, not included), and step.

scala>  List.range(1.5)
res34: List[Int] = List(1.2.3.4)

scala> List.range(1.9.2)
res35: List[Int] = List(1.3.5.7)

scala> List.range(9.1, -3)
res36: List[Int] = List(9.6.3)
Copy the code

7.2 the List. The fill

List.fill populates the List with the specified value.

scala> List.fill(3) ("hello")
res37: List[String] = List(hello, hello, hello)

scala> List.fill(2.3) ("world")
res38: List[List[String]] = List(List(world, world, world), List(world, world, world))
Copy the code

7.3 List. Concat

List.concat is used to concate multiple lists.

scala> List.concat(List('a'.'b'), List('c'))
res39: List[Char] = List(a, b, c)

scala> List.concat(List(), List('b'), List('c'))
res40: List[Char] = List(b, c)

scala> List.concat()
res41: List[Nothing] = List()
Copy the code

Handle multiple lists

When multiple lists are added to the same tuple, you can use Zipped to associate multiple lists.

// Multiply two elements at the corresponding positions of the List
scala> (List(10.20), List(3.4.5)).zipped.map(_ * _)
res42: List[Int] = List(30.80)

// The operations on the three lists are the same
scala> (List(10.20), List(3.4.5), List(100.200)).zipped.map(_ * _ + _)
res43: List[Int] = List(130.280)

// Determine whether the length of the elements in the first List is equal to the value of the elements in the second List
scala>  (List("abc"."de"), List(3.2)).zipped.forall(_.length == _)
res44: Boolean = true
Copy the code

ListBuffer

Since the underlying implementation of the List is a linked List, this means fast access to the head elements of the List, but less efficient access to the tail elements. The ListBuffer provides the ability to append elements to the head and tail in constant time.

import scala.collection.mutable.ListBuffer

object ScalaApp extends App {

  val buffer = new ListBuffer[Int]
  // 1. Append elements to the tail
  buffer += 1
  buffer += 2
  // 2. Append elements to headers
  3 +=: buffer
  // 3
  val list: List[Int] = buffer.toList
  println(list)
}

// List(3, 1, 2)
Copy the code

Ten, Set (Set)

A Set is a collection of non-repeating elements. There are mutable and immutable sets.

10.1 variable Set

object ScalaApp extends App {

  / / variable Set
  val mutableSet = new collection.mutable.HashSet[Int]

  // 1. Add elements
  mutableSet.add(1)
  mutableSet.add(2)
  mutableSet.add(3)
  mutableSet.add(3)
  mutableSet.add(4)

  // 2. Remove elements
  mutableSet.remove(2)
  
  // 3. Call the mkString method to print 1,3,4
  println(mutableSet.mkString(","))

  // 4. Get the smallest element in Set
  println(mutableSet.min)

  // 5. Get the largest element in Set
  println(mutableSet.max)

}
Copy the code

10.2 Immutable Set

Immutable sets have no add method. You can use + to add elements, but a new immutable Set is returned, unchanged.

object ScalaApp extends App {
  
  // immutable Set
  val immutableSet = new collection.immutable.HashSet[Int]

  val ints: HashSet[Int] = immutableSet+1

  println(ints)

}

/ / output Set (1)
Copy the code

10.3 Inter-set Operations

Multiple sets can be used to find intersection or Set.

object ScalaApp extends App {

  // declare an ordered Set
  val mutableSet = collection.mutable.SortedSet(1.2.3.4.5)
  val immutableSet = collection.immutable.SortedSet(3.4.5.6.7)
  
  // TreeSet(1, 2, 3, 4, 5, 6, 7)
  println(mutableSet ++ immutableSet)

  // TreeSet(3, 4, 5)
  println(mutableSet intersect immutableSet)

}
Copy the code

The resources

  1. Martin Odersky. Scala Programming (3rd edition)[M]. Publishing House of Electronics Industry. 2018-1-1
  2. Kay S. Horstman. Learn Scala quickly (2nd edition)[M]. Publishing House of Electronics Industry. 2017-7

See the GitHub Open Source Project: Getting Started with Big Data for more articles in the big Data series