Scala: построение среды разработки, переменные, решения, циклы, функции, коллекции (1)

Большие данные
Scala: построение среды разработки, переменные, решения, циклы, функции, коллекции (1)

Scala: построение среды разработки, переменные, решения, циклы, функции, коллекции

1. Введение в скалу

Скала работаетJVMВверхмультипарадигмальное программированиеязык, поддерживаяОбъектно-ориентированное программированиеифункциональное программирование

1572876978836

В первые дни, когда Scala впервые появилась, она не привлекала особого внимания, но с появлением основанных на Scala фреймворков для работы с большими данными, таких как Kafka и Spark, Scala постепенно попала в поле зрения разработчиков больших данных. Главное преимущество scala в том, что еговыразительный.

Далее мы должны учиться:

  • Зачем использовать SCALA?
  • Сравнение языка Java и языка Scala в двух случаях

1.1 Зачем использовать Скала

  • Разработка приложений для работы с большими данными (программы Spark, программы Flink)

  • Сильные выразительные способности, одна строка кода стоит нескольких строк Java, а скорость разработки высока.

  • Совместим с Java, может получить доступ к огромной библиотеке классов Java, может быть интегрирован в экосистему Hadoop.

    1572877057860

1.2 Скала против Java

В следующих двух случаях количество кодов, реализованных с использованием java и scala соответственно

кейс

Определите три класса сущностей (Пользователь, Заказ, Товар)

Java-код

/**
 * 用户实体类
 */
public class User {
    private String name;
    private List<Order> orders;

    public String getName() {
    	return name;
    }

    public void setName(String name) {
    	this.name = name;
    }

    public List<Order> getOrders() {
    	return orders;
    }

    public void setOrders(List<Order> orders) {
    	this.orders = orders;
    }
}
/**
 * 订单实体类
 */
public class Order {
    private int id;
    private List<Product> products;

    public int getId() {
    	return id;
    }

    public void setId(int id) {
    	this.id = id;
    }

    public List<Product> getProducts() {
    	return products;
    }

    public void setProducts(List<Product> products) {
    	this.products = products;
    }
}
/**
 * 商品实体类
 */
public class Product {
    private int id;
    private String category;

    public int getId() {
    	return id;
    }

    public void setId(int id) {
    	this.id = id;
    }

    public String getCategory() {
    	return category;
    }

    public void setCategory(String category) {
    	this.category = category;
    }
}

код скалы

case class User(var name:String, var orders:List[Order])	// 用户实体类
case class Order(var id:Int, var products:List[Product])	// 订单实体类
case class Product(var id:Int, var category:String)  		// 商品实体类

2. Установка среды разработки

Прежде чем научиться писать код Scala, вам необходимо установить компилятор Scala и инструменты разработки.

Процесс компиляции и выполнения Java-программы

1556551819121

Процесс компиляции и выполнения программы Scala

1556551904384

Выполнение программ Scala должно зависеть от библиотеки классов Java, которая должна иметьСреда выполнения Java, scala может выполняться корректно

Согласно приведенной выше блок-схеме, для компиляции и запуска программы scala вам необходимо:

  • JDK (JVM)
  • Компилятор scala (Scala SDK)

Далее необходимо последовательно установить следующее:

  • Установить JDK
  • Установите Скала SDK
  • Установить плагин ИДЕИ

2.1 Установите JDK

Установите 64-разрядную версию JDK 1.8 и настройте переменные среды.

2.2 Установите scala SDK

scala SDK — это компилятор для языка scala.Чтобы разработать программу scala, вы должны сначала установить SDK

На этот раз установлена ​​версия: 2.11.12.

шаг

  1. Скачайте и установите SDK
  2. Проверьте, прошла ли установка успешно

конкретная операция

платформа окон

  1. Разархивируйте scala-2.11.12.zip и установите scala вНет китайщины, нет пробелов в каталоге

  2. Настроить переменные среды

    SCALA_HOME=C:\Work\soft\scala-2.11.12
    path=%SCALA_HOME%\bin;
    
  3. Откройте консоль и введитеscala -version

платформа линукс

  1. Разархивируйте scala-2.11.12.tgz и установите scala вНет китайщины, нет пробелов в каталоге

  2. Настроить переменные среды

    tar -zxvf scala-2.11.12.tgz
    vi /etc/profile
    export SCALA_HOME=/export/servers/scala-2.11.12
    export PATH=$PATH:$SCALA_HOME/bin
    source /etc/profile
    

2.3 Установите подключаемый модуль IDEA scala

IDEA не поддерживает разработку программ Scala по умолчанию, поэтому вам необходимо установить подключаемый модуль scala для поддержки языка Scala.

шаг

  1. Скачать указанную версиюСкала-плагин IDEA
  2. IDEA настроить плагин scala
  3. перезапустить ИДЕЮ

конкретная операция

Операция 1: просмотр номера версии IDEA.

assets/1556509878949.png

Операция 2: Перейдите на официальный сайт IDEA, чтобы загрузить соответствующую версию.Скала-плагин IDEA

[!DANGER]

Обязательно загрузите плагин scala с той же версией IDEA.

Операция 3: Выберите «Конфигурация» > «Выбрать плагин».

assets/1556509878949.png

Операция 4: нажмите на маленькую шестеренку > выберите «Установить плагин из локальной сети».

从本地安装插件

Операция 5: найдите местоположение загруженного плагина и нажмите «ОК».

找打下载的插件位置

Операция 6.: перезапустить ИДЕЮ

Операция 7: Посмотреть подключаемый модуль scala

3. интерпретатор Скала

Позже мы воспользуемся интерпретатором scala для изучения базового синтаксиса scala.Интерпретатор scala, как и линуксовая команда, выполняет код, и сразу дает нам увидеть результат выполнения, что более удобно для тестирования.

Далее узнаем:

  • Запустить интерпретатор SCALA
  • Выполнить код Scala в интерпретаторе Scala
  • выйти из интерпретатора scala

3.1 Запустите интерпретатор scala

Чтобы запустить интерпретатор scala, необходимы только следующие шаги:

  • нажмите и удерживайтеwindows键 + r
  • входитьscalaПросто

1556552802175

3.2 Выполнение scala-кода

В окне командной строки scala введитеprintln("hello, world"), нажмите Enter, чтобы выполнить

1556552954626

3.3 Выход из интерпретатора

Выполнить в окне командной строки scala:quit, чтобы выйти из интерпретатора

4. Объявить переменные

В будущем мы будем определять переменные каждый день, когда будем писать программы на языке Scala. Как язык scala определяет переменные?

4.1 Формат синтаксиса

Определение переменной Java

int a = 0;

В scala вы можете использоватьvalилиvarДля определения переменных используется следующий синтаксис:

val/var 变量标识:变量类型 = 初始值

в

  • valопределяет переменную, которую нельзя переназначить
  • varОпределяет переменную, которую можно переназначить

[!NOTE]

  • Тип переменной, определенный в scala, записывается после имени переменной.
  • В операторе Scala не нужно добавлять точку с запятой в конце

4.2 Определение переменной в интерпретаторе

Пример: определите переменную для хранения имени человека "том"

шаг

  1. Открытый интерпретатор Scala
  2. Определите переменную типа string для хранения имени

Код ссылки

scala> val name:String = "tom"
name: String = tom

4.3 переменные val и var

Пример

Переназначьте переменную имени Джиму и наблюдайте за результатом ее работы.

Код ссылки

scala> name = "Jim"
<console>:12: error: reassignment to val
       name = "Jim"

Пример

использоватьvarПереопределите переменную, чтобы она содержала имя «том», и попробуйте переназначить ее Джиму и посмотрите на результат.

Код ссылки

scala> var name:String = "tom"
name: String = tom

scala> name = "Jim"
name: String = Jim

[!TIP]

Приоритетное использованиеvalОпределите переменную, используйте ее только в том случае, если переменная должна быть переназначенаvar

4.4 Использование вывода типов для определения переменных

Синтаксис Scala проще, чем у Java, и мы можем использовать более лаконичный способ определения переменных.

Пример

Определите переменную для хранения имени человека «том», используя более краткий синтаксис.

Код ссылки

scala> val name = "tom"
name: String = tom

Scala может автоматически определять тип переменной на основе значения переменной, что делает написание кода более кратким.

4.5 Ленивое назначение

При разработке корпоративных больших данных иногда пишутся очень сложные операторы SQL, и эти операторы SQL могут состоять из сотен или даже тысяч строк. Эти операторы SQL, если они загружены непосредственно в JVM, будут иметь большие накладные расходы памяти. Как решить?

Когда есть какие-то переменные, которые содержат большие данные, но их не нужно сразу загружать в память JVM. можно использоватьленивое заданиедля повышения эффективности.

Формат синтаксиса:

lazy val/var 变量名 = 表达式

Пример

Следующий сложный оператор SQL должен быть выполнен в программе, и мы надеемся загрузить его только при использовании этого оператора SQL.

"""insert overwrite table adm.itcast_adm_personas
    select
    a.user_id,
    a.user_name,
    a.user_sex,
    a.user_birthday,
    a.user_age,
    a.constellation,
    a.province,
    a.city,
    a.city_level,
    a.hex_mail,
    a.op_mail,
    a.hex_phone,
    a.fore_phone,
    a.figure_model,
    a.stature_model,
    b.first_order_time,
    b.last_order_time,
      ...
    d.month1_hour025_cnt,
    d.month1_hour627_cnt,
    d.month1_hour829_cnt,
    d.month1_hour10212_cnt,
    d.month1_hour13214_cnt,
    d.month1_hour15217_cnt,
    d.month1_hour18219_cnt,
    d.month1_hour20221_cnt,
    d.month1_hour22223_cnt
    from gdm.itcast_gdm_user_basic a
      left join gdm.itcast_gdm_user_consume_order b on a.user_id=b.user_id
    left join gdm.itcast_gdm_user_buy_category c on a.user_id=c.user_id
    left join gdm.itcast_gdm_user_visit d on a.user_id=d.user_id;"""

Код ссылки

scala> lazy val sql = """insert overwrite table adm.itcast_adm_personas
     |     select
     |     a.user_id,
	....
     |     left join gdm.itcast_gdm_user_buy_category c on a.user_id=c.user_id
     |     left join gdm.itcast_gdm_user_visit d on a.user_id=d.user_id;"""
sql: String = <lazy>

5. Струны

Scala предоставляет множество способов определения строк, и в будущем мы сможем выбрать наиболее удобный способ определения строк в соответствии с нашими потребностями.

  • использовать двойные кавычки
  • Используйте интерполяционные выражения
  • использовать тройные кавычки

5.1 Использование двойных кавычек

грамматика

val/var 变量名 = “字符串”

Пример

Есть человек по имени "hadoop", напечатайте его имя и длину его имени.

Код ссылки

scala> println(name + name.length)
hadoop6

5.2 Использование интерполяционных выражений

В scala выражения интерполяции могут использоваться для определения строк, эффективно избегая конкатенации большого количества строк.

грамматика

val/var 变量名 = s"${变量/表达式}字符串"

[!TIP]

  • добавить перед строкой определенияs
  • В строке вы можете использовать${}для ссылки на переменные или записи выражений

Пример

Пожалуйста, определите количество переменных, сохраните: "ZHANGSAN", 30, "MALE", определите строку для сохранения этой информации.

Распечатка: имя=чжансан, возраст=30, пол=мужской

Код ссылки

scala> val name = "zhangsan"
name: String = zhangsan

scala> val age = 30
age: Int = 30

scala> val sex = "male"
sex: String = male

scala> val info = s"name=${name}, age=${age}, sex=${sex}"
info: String = name=zhangsan, age=30, sex=male

scala> println(info)
name=zhangsan, age=30, sex=male

5.3 Использование тройных кавычек

Если необходимо сохранить большой фрагмент текста, вы можете использовать тройные кавычки для определения строки. Например: сохраните большой оператор SQL. Все строки между тремя кавычками будут использоваться как строковые значения.

грамматика

val/var 变量名 = """字符串1
字符串2"""

Пример

Определите строку, содержащую следующую инструкцию SQL

select
	*
from
    t_user
where
    name = "zhangsan"

распечатать оператор SQL

Код ссылки

val sql = """select
     | *
     | from
     |     t_user
     | where
     |     name = "zhangsan""""

println(sql)

6. Типы данных и операторы

Большинство типов и операторов в scala такие же, как и в Java, в основном изучаем

  • Некоторые способы использования, отличные от Java
  • система наследования типов scala

6.1 Типы данных

базовый тип Описание типа
Byte 8-битное целое число со знаком
Short 16-битное целое число со знаком
Int 32-битное целое число со знаком
Long 64-битное целое число со знаком
Char 16-битные беззнаковые символы Unicode
String Последовательность типа Char (строка)
Float 32-битное число с плавающей запятой одинарной точности
Double 64-битное число двойной точности с плавающей запятой
Boolean правда или ложь

Обратите внимание на разницу между типами scala и Java.

[!NOTE]

  1. Все типы в scala используютпрописная букваначало
  2. использование пластикаIntвместо целого числа
  3. Вы можете определить переменные в scala, не записывая типы, и позволить компилятору scala автоматически вывести

6.2 Операторы

категория оператор
арифметические операторы +, -, *, /
оператор отношения >, =,
Логические операторы &&, ||, !
побитовые операторы &, ||, ^, >
  • Там нет ++, - оператор в Scala

  • В отличие от Java, в scala вы можете напрямую использовать==,!=сравните их сequalsметод последователен. А для сравнения эталонных значений двух объектов используйтеeq

Пример

Есть строка "abc", а затем создайте вторую строку со значением: объединить пустую строку после первой строки.

Затем сравните эти две строки равны, затем ссылочное значение, чтобы увидеть, равны ли они.

Код ссылки

val str1 = "abc"
val str2 = str1 + ""
str1 == str2
str1.eq(str2)

6.3 Иерархия типов scala

1556592270468

тип инструкция
Any все типыРодительский класс, имеет два подкласса AnyRef и AnyVal
AnyVal все числовые типыродительский класс
AnyRef Родительский класс всех типов объектов (ссылочные типы)
Unit Указывает пусто, Unit является подклассом AnyVal, имеет только один экземпляр {% em %}() {% endem %}
Это похоже на void в Java, но scala более объектно-ориентирована, чем Java.
Null Null является подклассом AnyRef, что означает, что он является подклассом всех ссылочных типов. Его экземпляр {% em %}null{% endem %}
Вы можете присвоить null любому типу объекта
Nothing все типыПодкласс
Экземпляр этого типа нельзя создать напрямую, когда метод выдает исключение, он возвращает тип Nothing, потому что Nothing является подклассом всех классов, поэтому его можно присвоить любому типу

проблема

Что-то не так со следующим кодом?

val b:Int = null

Scala объяснит ошибку:

Тип Null не может быть преобразован в тип Int, что указываетNull не является подклассом Int

7. Условные выражения

Условное выражение — это выражение if.Выражение if может принять решение о выполнении соответствующей операции в соответствии с результатом условия (истина или ложь) в зависимости от того, выполняется ли данное условие. Условные выражения Scala имеют тот же синтаксис, что и Java.

7.1 если с возвращаемым значением

В отличие от Java,

[!NOTE]

  • В scala условные выражения также имеют возвращаемые значения.
  • В scala нет троичного выражения, вы можете использовать выражение if вместо троичного выражения

Пример

Определите переменную пола и определите переменную результата, если пол равен «мужской», результат равен 1, иначе результат равен 0

Код ссылки

scala> val sex = "male"
sex: String = male

scala> val result = if(sex == "male") 1 else 0
result: Int = 1

7.2 Блочные выражения

  • В scala используйте {} для представления выражения блока
  • Подобно выражениям if, блочные выражения имеют значения
  • значение - это значение последнего выражения

проблема

Каково значение переменной a в следующем коде?

scala> val a = {
     | println("1 + 1")
     | 1 + 1
     | }

8. Петля

В scala можно использовать for и while, но for выражения обычно рекомендуются, потому что синтаксис for выражений более лаконичен.

8.1 для выражений

грамматика

for(i <- 表达式/数组/集合) {
    // 表达式
}

8.1.1 Простой цикл

Используйте for выражение для печати чисел от 1 до 10

шаг

  1. Сгенерируйте числа 1-10 (подсказка: используйте метод to)
  2. Используйте for выражение для повторения и печати каждого числа

Справочный код 1

scala> val nums = 1.to(10)                                                              
nums: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 
                                                                                        
scala> for(i <- nums) println(i)                                                                                                                                          

стенография

Справочный код 2

// 中缀调用法
scala> for(i <- 1 to 10) println(i)

8.1.2 Вложенные циклы

Используя выражение for, выведите следующие символы

*****
*****
*****

шаг

  1. Используйте для выражения, чтобы напечатать 3 строки, 5 столбцов звезд
  2. Перенос строки каждые 5 напечатанных звезд

Код ссылки

for(i <- 1 to 3; j <- 1 to 5) {print("*");if(j == 5) println("")}

8.1.3 Охранник

В выражение for вы можете добавить оператор if, и это суждение называется охраной. Мы можем использовать охранники, чтобы сделать выражения for более краткими.

грамматика

for(i <- 表达式/数组/集合 if 表达式) {
    // 表达式
}

Пример

Использование для выражения может печатать от 1 до 10 чисел, кратных 3

Код ссылки

// 添加守卫,打印能够整除3的数字
for(i <- 1 to 10 if i % 3 == 0) println(i)

8.1.4 для понимания

  • В дальнейшем новый набор (набор данных) может быть сгенерирован с использованием для понимания

  • В теле цикла for можно использовать выражение yield для построения набора, мы вызываем выражение for, используя выражение yield a comprehension

Пример

Создайте набор из 10, 20, 30...100

Код ссылки

// for推导式:for表达式中以yield开始,该for表达式会构建出一个集合
val v = for(i <- 1 to 10) yield i * 10

8.2 циклы while

Цикл while в scala такой же, как в Java.

Пример

печатать числа 1-10

Код ссылки

scala> var i = 1
i: Int = 1

scala> while(i <= 10) {
     | println(i)
     | i = i+1
     | }

8.3 перерыв и продолжение

  • В scala удалены ключевые слова break/continue, такие как Java и C++.
  • Если вы должны использовать break/continue, вам нужно использовать класс Break пакета scala.util.controlbreableиbreakметод.

8.3.1 Реализация перерыва

использование

  • Импортируйте пакет «Перерывы»import scala.util.control.Breaks._
  • Выражение для использования разбивкой
  • Для выражения надо надо выйти из цикла, добавитьbreak()вызов метода

Пример

Используйте выражение for для печати чисел от 1 до 100, если число достигает 50, выйдите из выражения for

Код ссылки

// 导入scala.util.control包下的Break
import scala.util.control.Breaks._

breakable{
    for(i <- 1 to 100) {
        if(i >= 50) break()
        else println(i)
    }
}

8.3.2 Реализация продолжения

использование

Реализация continue аналогична break с одним отличием:

[!NOTE]

Реализация break заключается в заключении всего выражения for в breakable{}, а реализация continue заключается в заключении тела цикла выражения for в breakable{}.

Пример

Вывести числа от 1 до 100, использовать выражение for для обхода, если число делится на 10, не выводить

// 导入scala.util.control包下的Break    
import scala.util.control.Breaks._

for(i <- 1 to 100 ) {
    breakable{
        if(i % 10 == 0) break()
        else println(i)
    }
}

9. Метод

Класс может иметь свои собственные методы, а методы в scala аналогичны методам в Java. Но синтаксис определения методов в scala и Java отличается.

9.1 Определение метода

грамматика

def methodName (参数名:参数类型, 参数名:参数类型) : [return type] = {
    // 方法体:一系列的代码
}

[!NOTE]

  • Тип параметра списка параметров не может быть опущен
  • Тип возвращаемого значения может быть опущен и автоматически определяется компилятором scala.
  • Возвращаемое значение не может быть записано как return, по умолчанию используется значение выражения блока {}

Пример

  1. Определить метод для сложения двух целочисленных значений и возврата результата сложения
  2. вызовите этот метод

Код ссылки

scala> def add(a:Int, b:Int) = a + b
m1: (x: Int, y: Int)Int

scala> add(1,2)
res10: Int = 3

9.2 Вывод типа возвращаемого значения

Scala определяет метод, который может опускать возвращаемое значение, и Scala автоматически определяет тип возвращаемого значения. Таким образом, метод определяется более кратко.

[!DANGER]

Определите рекурсивный метод, тип возвращаемого значения не может быть опущен

Пример

Определить рекурсивный метод (найти факториал)

10 * 9 * 8 * 7 * 6 * ... * 1

Код ссылки

scala> def m2(x:Int) = {
     | if(x<=1) 1
     | else m2(x-1) * x
     | }
<console>:13: error: recursive method m2 needs result type
       else m2(x-1) * x

9.3 Параметры метода

Параметры метода в scala более гибкие в использовании. Он поддерживает следующие типы параметров:

  • параметры по умолчанию
  • именованный параметр
  • параметр переменной длины

9.3.1 Параметры по умолчанию

При определении метода вы можете определить значение по умолчанию для параметра.

Пример

  1. Определите метод, который вычисляет сложение двух значений, которые по умолчанию равны 0.
  2. Вызовите этот метод без передачи каких-либо параметров

Код ссылки

// x,y带有默认值为0 
def add(x:Int = 0, y:Int = 0) = x + y
add()

9.3.2 Именованные параметры

При вызове метода вы можете указать имя вызываемого параметра.

Пример

  1. Определите метод, который вычисляет сложение двух значений, которые по умолчанию равны 0.
  2. Вызовите этот метод, задав только значение первого параметра

Код ссылки

def add(x:Int = 0, y:Int = 0) = x + y
add(x=1)

9.3.3 Параметры переменной длины

Если параметры метода не фиксированы, вы можете определить параметр метода как параметр переменной длины.

Формат синтаксиса:

def 方法名(参数名:参数类型*):返回值类型 = {
    方法体
}

[!NOTE]

добавить один после типа параметра*число, указывающее, что параметр может быть 0 или более

Пример

  1. Определите метод, который вычисляет сложение нескольких значений
  2. Вызовите метод, передав следующие данные: 1,2,3,4,5

Код ссылки

scala> def add(num:Int*) = num.sum
add: (num: Int*)Int

scala> add(1,2,3,4,5)
res1: Int = 15

9.4 Метод вызова метода

В scala есть следующие методы для вызова:

  • метод вызова суффикса
  • инфиксный метод вызова
  • вызов фигурной скобки
  • вызов без скобок

Мы будем использовать вызовы этих методов при написании программ spark и flink в будущем.

9.4.1 Метод вызова суффикса

Этот подход ничем не отличается от Java.

грамматика

对象名.方法名(参数)

Пример

использовать суффиксMath.absнайти абсолютное значение

Код ссылки

scala> Math.abs(-1)
res3: Int = 1

9.4.2 Инфиксный метод вызова

грамматика

对象名 方法名 参数

Например:1 to 10

[!TIP]

Если параметров несколько, заключите их в круглые скобки.

Пример

использовать инфиксMath.absнайти абсолютное значение

scala> Math abs -1
res4: Int = 1

операторы - это методы

посмотрите на выражение

1 + 1

Как вы думаете, приведенное выше выражение похоже на вызов метода?

В scala такие операторы, как +-*/%, такие же, как в Java, но в scala,

  • Все операторы являются методами
  • Оператор — это метод, имя метода которого является символом

9.4.3 Вызов с помощью фигурных скобок

грамматика

Math.abs{ 
    // 表达式1
    // 表达式2
}

[!DANGER]

Метод только с одним параметром можно вызвать с помощью фигурных скобок

Пример

Вызов с фигурными скобкамиMath.absнайти абсолютное значение

Код ссылки

scala> Math.abs{-10}
res13: Int = 10

9.4.4 Вызов без круглых скобок

Если у метода нет параметров, скобки после имени метода можно опустить.

Пример

  • Определите метод без параметров, который печатает «привет»
  • вызовите метод, используя метод вызова без скобок

Код ссылки

def m3()=println("hello")
m3()

10. Функции

Scala поддерживает функциональное программирование, в будущем программы Spark/Flink будут использовать множество функций

10.1 Определение функций

грамматика

val 函数变量名 = (参数名:参数类型, 参数名:参数类型....) => 函数体

[!TIP]

  • функция представляет собойобъект(Переменная)
  • Подобно методам, функции также имеют входные параметры и возвращаемые значения.
  • В определениях функций не нужно использоватьdefопределение
  • Нет необходимости указывать тип возвращаемого значения

Пример

  1. Определите функцию, которая складывает два числа
  2. вызвать функцию

Код ссылки

scala> val add = (x:Int, y:Int) => x + y
add: (Int, Int) => Int = <function2>

scala> add(1,2)
res3: Int = 3

10.2 Разница между методами и функциями

  • Метод является частью класса или объекта, который во время выполнения загружается в область методов JVM.
  • Вы можете назначить функциональный объект переменной, которая загружается в память кучи JVM во время выполнения.
  • Функция — это объект, который наследуется от FunctionN. Объект функции имеет такие методы, как apply, curried, toString и tuple. метод не

Пример

Метод не может быть назначен переменной

scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int

scala> val a = add
<console>:12: error: missing argument list for method add
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `add _` or `add(_,_)` instead of `add`.
       val a = add

10.3 Преобразование методов в функции

  • Иногда вам нужно преобразовать метод в функцию и передать его как переменную, вам нужно преобразовать метод в функцию

  • использовать_преобразовать метод в функцию

Пример

  1. Определите метод для добавления двух чисел
  2. Преобразуйте метод в функцию и назначьте его переменной

Код ссылки

scala> def add(x:Int,y:Int)=x+y
add: (x: Int, y: Int)Int

scala> val a = add _
a: (Int, Int) => Int = <function2>

11. Массивы

Концепция массива в scala аналогична концепции в Java, и массив можно использовать для хранения набора данных. В scala есть два вида массивов, один из нихмассив фиксированной длины, другоймассив переменной длины

11.2 Массивы фиксированной длины

  • Массив фиксированной длины относится к массивудлинадане разрешено изменятьиз
  • массивэлементдаможно изменитьиз

грамматика

// 通过指定长度定义数组
val/var 变量名 = new Array[元素类型](数组长度)

// 用元素直接初始化数组
val/var 变量名 = Array(元素1, 元素2, 元素3...)

[!NOTE]

  • В scala дженерики для массивов используют[]указать

  • использовать()чтобы получить элемент

Пример 1

  1. Определить целочисленный массив длины 100
  2. Установите первый элемент на 110
  3. напечатать первый элемент

Код ссылки

scala> val a = new Array[Int](100)
a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

scala> a(0) = 110

scala> println(a(0))
110

Пример 2

  1. Определите массив со следующими элементами

    "java", "scala", "python"
    
  2. получить длину массива

Код ссылки

// 定义包含jave、scala、python三个元素的数组
scala> val a = Array("java", "scala", "python")
a: Array[String] = Array(java, scala, python)

scala> a.length
res17: Int = 3

11.3 Массивы переменной длины

Массив переменной длины означает, что длина массива является переменной, и элементы могут добавляться и удаляться в массив.

11.3.1 Определение массивов переменной длины

Для создания массива переменной длины необходимо заранее импортировать класс ArrayBufferimport scala.collection.mutable.ArrayBuffer

грамматика

  • Создайте пустой массив переменной длины ArrayBuffer, структура синтаксиса:

    val/var a = ArrayBuffer[元素类型]()
    
  • Создайте ArrayBuffer с начальными элементами

    val/var a = ArrayBuffer(元素1,元素2,元素3....)
    

Пример 1

Определить целочисленный массив переменной длины длины 0

Код ссылки

val a = ArrayBuffer[Int]()

Пример 2

Определите массив переменной длины, содержащий следующие элементы

"hadoop", "storm", "spark"

Код ссылки

scala> val a = ArrayBuffer("hadoop", "storm", "spark")
a: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(hadoop, storm, spark)

11.3.2 Добавление/изменение/удаление элементов

  • использовать+=добавить элемент
  • использовать-=удалить элемент
  • использовать++=Добавить массив к массиву переменной длины

Пример

  1. Определите массив переменной длины со следующими элементами: "hadoop", "spark", "flink"
  2. Добавьте элемент «лоток» в массив переменной длины.
  3. удалить элемент "hadoop" из массива переменной длины
  4. Добавьте еще один массив, содержащий "hive", "sqoop", к массиву переменной длины.

Код ссылки

// 定义变长数组
scala> val a = ArrayBuffer("hadoop", "spark", "flink")
a: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(hadoop, spark, flink)

// 追加一个元素
scala> a += "flume"
res10: a.type = ArrayBuffer(hadoop, spark, flink, flume)

// 删除一个元素
scala> a -= "hadoop"
res11: a.type = ArrayBuffer(spark, flink, flume)

// 追加一个数组
scala> a ++= Array("hive", "sqoop")
res12: a.type = ArrayBuffer(spark, flink, flume, hive, sqoop)

11.4 Обход массива

Существует два способа перебора массива:

  • использоватьfor表达式Итерация непосредственно по элементам в массиве

  • использовать索引перебирать элементы в массиве

Пример 1

  1. Определите массив, содержащий следующие элементы 1,2,3,4,5
  2. Используйте выражение for для прямого обхода и печати элементов массива.

Код ссылки

scala> val a = Array(1,2,3,4,5)
a: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for(i<-a) println(i)
1
2
3
4
5

Пример 2

  1. Определите массив, содержащий следующие элементы 1,2,3,4,5
  2. Используйте выражение for для обхода на основе нижнего индекса индекса и печати элементов массива.

Код ссылки

scala> val a = Array(1,2,3,4,5)
a: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for(i <- 0 to a.length - 1) println(a(i))
1
2
3
4
5

scala> for(i <- 0 until a.length) println(a(i))
1
2
3
4
5

[!NOTE]

0 до n - сгенерировать серию чисел, включая 0, исключая n

от 0 до n - включая 0, также включает n

11.5 Общие алгоритмы для массивов

Массивы в scala инкапсулируют некоторые общие вычислительные операции, в дальнейшем при обработке данных нам не нужно будет заново их реализовывать самостоятельно. Ниже приведены некоторые часто используемые алгоритмы:

  • Суммирование - метод суммы
  • Найдите максимальное значение - метод max
  • Найдите минимальное значение - метод min
  • Сортировать - метод сортировки

11.5.1 Суммирование

в массивеsumМетод может аккумулировать все элементы, а затем получить результат

Пример

  1. Определите массив, содержащий следующие элементы (1,2,3,4)
  2. Вычислите сумму этого массива

Код ссылки

scala> val a = Array(1,2,3,4)
a: Array[Int] = Array(1, 2, 3, 4)

scala> a.sum
res49: Int = 10

11.5.2 Максимальное значение

в массивеmaxметод, вы можете получить наибольшее значение элемента в массиве

Пример

  1. Определите массив, содержащий следующие элементы (4,1,2,4,10)
  2. Получить максимальное значение массива

Код ссылки

scala> val a = Array(4,1,2,4,10)
a: Array[Int] = Array(4, 1, 2, 4, 10)

scala> a.max
res50: Int = 10

11.5.3 Минимальное значение

массивminметод, вы можете получить наименьшее значение элемента в массиве

Пример

  1. Определите массив, содержащий следующие элементы (4,1,2,4,10)
  2. Получить минимальное значение массива

Код ссылки

scala> val a = Array(4,1,2,4,10)
a: Array[Int] = Array(4, 1, 2, 4, 10)

scala> a.min
res51: Int = 1

11.5.4 Сортировка

массивsortedМетод сортировки массива в порядке возрастания. иreverseметод обращения массива для сортировки в порядке убывания

Пример

  1. Определите массив, содержащий следующие элементы (4,1,2,4,10)
  2. Отсортировать массив в порядке возрастания и убывания

Код ссылки

// 升序排序
scala> a.sorted
res53: Array[Int] = Array(1, 2, 4, 4, 10)

// 降序
scala> a.sorted.reverse
res56: Array[Int] = Array(10, 4, 4, 2, 1)

12. Кортежи

Кортежи могут использоваться для хранения набора значений разных типов. Например: имя, возраст, пол, дата рождения. Элементы кортежа неизменяемы.

12.1 Определение кортежей

грамматика

Используйте круглые скобки для определения кортежей

val/var 元组 = (元素1, 元素2, 元素3....)

Используйте стрелки для определения кортежей (кортежи состоят только из двух элементов)

val/var 元组 = 元素1->元素2

Пример

Определите кортеж, содержащий следующие данные для учащегося

id Имя возраст адрес
1 zhangsan 20 beijing

Код ссылки

scala> val a = (1, "zhangsan", 20, "beijing")
a: (Int, String, Int, String) = (1,zhangsan,20,beijing)

Пример

  • Определите кортеж, содержащий имя и возраст учащегося (zhangsan, 20)
  • Используйте круглые скобки и стрелки для определения кортежей соответственно.

Код ссылки

scala> val a = ("zhangsan", 20)
a: (String, Int) = (zhangsan,20)

scala> val a = "zhangsan" -> 20
a: (String, Int) = (zhangsan,20)

12.2 Доступ к кортежам

Используйте _1, _2, _3.... для доступа к элементам в кортеже, _1 для доступа к первому элементу и т. д.

Пример

  • Определите кортеж, содержащий имя и пол учащегося, «чжансан», «мужской».
  • Получить имя и пол учащегося отдельно

Код ссылки

scala> val a = "zhangsan" -> "male"
a: (String, String) = (zhangsan,male)

// 获取第一个元素
scala> a._1
res41: String = zhangsan

// 获取第二个元素
scala> a._2
res42: String = male

13. Список

Списки — самая важная и наиболее часто используемая структура данных в scala. Список обладает следующими свойствами:

  • Может сохранять повторяющиеся значения
  • чтобы

В scala также есть два вида списков: один — неизменяемый список, а другой — изменяемый список.

13.1 Неизменяемые списки

определение

Неизменяемый список — это список, элементы и длина которого неизменны.

грамматика

использоватьList(元素1, 元素2, 元素3, ...)Для создания неизменяемого списка используется следующий синтаксис:

val/var 变量名 = List(元素1, 元素2, 元素3...)

использоватьNilСоздать неизменяемый пустой список

val/var 变量名 = Nil

использовать::метод создания неизменяемого списка

val/var 变量名 = 元素1 :: 元素2 :: Nil

[!TIP]

использовать**::сращивание для создания списка, вы должны добавить один в концеNil**

Пример 1

Создайте неизменяемый список со следующими элементами (1,2,3,4)

Код ссылки

scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

Пример 2

Создайте неизменяемый пустой список с Nil

Код ссылки

scala> val a = Nil
a: scala.collection.immutable.Nil.type = List()

Пример третий

использовать::Метод создает список с двумя элементами -2 и -1.

Код ссылки

scala> val a = -2 :: -1 :: Nil
a: List[Int] = List(-2, -1)

13.2 Изменяемые списки

Изменяемый список — это список, элементы и длина которого являются переменными.

Чтобы использовать изменяемые списки, сначала импортируйтеimport scala.collection.mutable.ListBuffer

[!NOTE]

  • Изменяемые коллекцииmutableв сумке
  • Неизменяемые коллекцииimmutableпакет (импортируется по умолчанию)

определение

Используйте ListBuffer[element type]() для создания пустого изменяемого списка, структура синтаксиса:

val/var 变量名 = ListBuffer[Int]()

Используйте ListBuffer (элемент 1, элемент 2, элемент 3...) для создания изменяемого списка, структура синтаксиса:

val/var 变量名 = ListBuffer(元素1,元素2,元素3...)

Пример 1

Создайте пустой изменяемый список целых чисел

Код ссылки

  scala> val a = ListBuffer[Int]()
  a: scala.collection.mutable.ListBuffer[Int] = ListBuffer()

Пример 2

Создайте изменяемый список со следующими элементами: 1,2,3,4

Код ссылки

scala> val a = ListBuffer(1,2,3,4)
a: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)

13.3. Операции с изменяемым списком

  • Получить элемент (доступ через круглые скобки(索引值))
  • добавить элемент (+=)
  • добавить список (++=)
  • меняй элемент(使用括号获取元素,然后进行赋值)
  • удалить элемент (-=)
  • Преобразовать в список(toList)
  • Преобразовать в массив(toArray)

Пример

  1. Определите изменяемый список, содержащий следующие элементы: 1,2,3
  2. получить первый элемент
  3. Добавить новый элемент: 4
  4. Добавьте список со следующими элементами: 5,6,7
  5. удалить элемент 7
  6. Преобразование изменяемого списка в неизменяемый список
  7. Преобразование изменяемого списка в массив

Код ссылки

// 导入不可变列表
scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer

// 创建不可变列表
scala> val a = ListBuffer(1,2,3)
a: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)

// 获取第一个元素
scala> a(0)
res19: Int = 1

// 追加一个元素
scala> a += 4
res20: a.type = ListBuffer(1, 2, 3, 4)

// 追加一个列表
scala> a ++= List(5,6,7)
res21: a.type = ListBuffer(1, 2, 3, 4, 5, 6, 7)

// 删除元素
scala> a -= 7
res22: a.type = ListBuffer(1, 2, 3, 4, 5, 6)

// 转换为不可变列表
scala> a.toList
res23: List[Int] = List(1, 2, 3, 4, 5, 6)

// 转换为数组
scala> a.toArray
res24: Array[Int] = Array(1, 2, 3, 4, 5, 6)

13.4 Список общих операций

Ниже приведены часто используемые операции для списков.

  • Проверьте, не пуст ли список (isEmpty)
  • объединить два списка (++)
  • Получить первый элемент списка (head) и остаток (tail)
  • перевернуть список(reverse)
  • получить префикс (take), получить суффикс (drop)
  • Плоский(flaten)
  • молния(zip) и оторваться (unzip)
  • преобразовать строку (toString)
  • создать строку (mkString)
  • союз (union)
  • перекресток (intersect)
  • разница (diff)

13.4.1 Определение того, является ли список пустым

Пример

  • Определите список со следующими элементами: 1,2,3,4
  • Используйте isEmpty, чтобы проверить, пуст ли список.

Код ссылки

scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

scala> a.isEmpty
res51: Boolean = false

13.4.2 Объединение двух списков

Пример

  • Есть два списка со следующими элементами 1,2,3 и 4,5,6
  • использовать++объединить два списка

Код ссылки

scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)

scala> val b = List(4,5,6)
b: List[Int] = List(4, 5, 6)

scala> a ++ b
res52: List[Int] = List(1, 2, 3, 4, 5, 6)

13.4.3 Получение первого элемента и остатка списка

Пример

  • Определите список со следующими элементами: 1,2,3
  • Используйте метод head, чтобы получить первый элемент списка
  • Используя хвостовой метод, получить элементы, отличные от первого элемента, который также является списком

Код ссылки

scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)

scala> a.head
res4: Int = 1

scala> a.tail
res5: List[Int] = List(2, 3)

13.4.4 Инверсия списка

Пример

  • Определите список со следующими элементами: 1,2,3

  • Используйте обратный метод, чтобы перевернуть элементы списка

scala> val a = List(1,2,3)
a: List[Int] = List(1, 2, 3)

scala> a.reverse
res6: List[Int] = List(3, 2, 1)

13.4.5 Получение префикса и суффикса списка

Пример

  • Определите список со следующими элементами: 1,2,3,4,5
  • Используйте метод take, чтобы получить префикс (первые три элемента): 1, 2, 3.
  • Используйте метод отбрасывания, чтобы получить суффикс (элементы, отличные от первых трех): 4,5

Код ссылки

scala> val a = List(1,2,3,4,5)
a: List[Int] = List(1, 2, 3, 4, 5)

scala> a.take(3)
res56: List[Int] = List(1, 2, 3)

scala> a.drop(3)
res60: List[Int] = List(4, 5)

13.4.6 Сведение (сведение)

Сведение означает объединение всех элементов списка в один список.

1557063067562

Пример

  • Есть список, и список содержит три списка, а именно: Список(1,2), Список(3), Список(4,5)
  • Используйте flatten, чтобы преобразовать этот список в список (1,2,3,4,5)

Код ссылки

scala> val a = List(List(1,2), List(3), List(4,5))
a: List[List[Int]] = List(List(1, 2), List(3), List(4, 5))

scala> a.flatten
res0: List[Int] = List(1, 2, 3, 4, 5)

13.4.7 Архивация и распаковка

  • zip: Используйте zip для объединения двух списков в список кортежей.
  • Распаковать: распаковать список кортежей в кортеж из двух списков.

Пример

  • Есть два списка
    • В первом списке указаны имена трех учеников: Чжансан, Лиси, Вану.
    • Второй список содержит возраст трех студентов: 19, 20, 21 год.
  • Используйте операцию zip, чтобы «стянуть» данные двух списков вместе, чтобы сформировать zhangsan-> 19, lisi -> 20, wangwu-> 21

Код ссылки

scala> val a = List("zhangsan", "lisi", "wangwu")
a: List[String] = List(zhangsan, lisi, wangwu)

scala> val b = List(19, 20, 21)
b: List[Int] = List(19, 20, 21)

scala> a.zip(b)
res1: List[(String, Int)] = List((zhangsan,19), (lisi,20), (wangwu,21))

Пример

  • Распакуйте приведенный выше список кортежей, содержащих имена и возраст учащихся, в два списка.

Код ссылки

scala> res1.unzip
res2: (List[String], List[Int]) = (List(zhangsan, lisi, wangwu),List(19, 20, 21))

13.4.8 Преобразование строк

Метод toString может возвращать все элементы в списке

Пример

  • Определите список со следующими элементами: 1,2,3,4
  • Используйте toString для вывода элементов этого списка

Код ссылки

scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

scala> println(a.toString)
List(1, 2, 3, 4)

13.4.9 Генерация строк

Метод mkString может объединять элементы с разделителями. Без разделителя по умолчанию

Пример

  • Определите список, содержащий следующие элементы 1,2,3,4
  • Используйте mkString для объединения элементов с двоеточиями.

Код ссылки

scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

scala> a.mkString
res7: String = 1234

scala> a.mkString(":")
res8: String = 1:2:3:4

13.4.10 Союз

union означает объединение двух списков без дедупликации

Пример

  • Определите первый список, содержащий следующие элементы: 1,2,3,4
  • Определите второй список со следующими элементами: 3,4,5,6
  • Используйте операцию объединения, чтобы получить объединение этих двух списков.
  • Используйте отдельную операцию для удаления повторяющихся элементов

Код ссылки

scala> val a1 = List(1,2,3,4)
a1: List[Int] = List(1, 2, 3, 4)

scala> val a2 = List(3,4,5,6)
a2: List[Int] = List(3, 4, 5, 6)

// 并集操作
scala> a1.union(a2)
res17: List[Int] = List(1, 2, 3, 4, 3, 4, 5, 6)

// 可以调用distinct去重
scala> a1.union(a2).distinct
res18: List[Int] = List(1, 2, 3, 4, 5, 6)

13.4.11 Перекресток

intersect означает пересечение двух списков

Пример

  • Определите первый список, содержащий следующие элементы: 1,2,3,4
  • Определите второй список со следующими элементами: 3,4,5,6
  • Используйте операцию пересечения, чтобы получить пересечение этих двух списков.
scala> val a1 = List(1,2,3,4)
a1: List[Int] = List(1, 2, 3, 4)

scala> val a2 = List(3,4,5,6)
a2: List[Int] = List(3, 4, 5, 6)

scala> a1.intersect(a2)
res19: List[Int] = List(3, 4)

13.4.12 Разница

diff означает взять разницу между двумя списками, например: a1.diff(a2), означает получить элементы a1, которые не существуют в a2

Пример

  • Определите первый список, содержащий следующие элементы: 1,2,3,4
  • Определите второй список со следующими элементами: 3,4,5,6
  • Используйте diff, чтобы получить разницу между этими двумя списками
scala> val a1 = List(1,2,3,4)
a1: List[Int] = List(1, 2, 3, 4)

scala> val a2 = List(3,4,5,6)
a2: List[Int] = List(3, 4, 5, 6)

scala> a1.diff(a2)
res24: List[Int] = List(1, 2)

14. Set

Set — это коллекция, не представляющая повторяющихся элементов. Набор обладает следующими свойствами:

  1. Элементы не повторяются
  2. Порядок размещения не гарантируется

В scala также есть два типа наборов: один — неизменяемый набор, а другой — изменяемый набор.

14.1 Неизменяемые множества

14.1.1 Определения

грамматика

Создайте пустой неизменяемый набор, формат синтаксиса:

val/var 变量名 = Set[类型]()

Чтобы создать неизменяемый набор заданных элементов, используется следующий синтаксис:

val/var 变量名 = Set(元素1, 元素2, 元素3...)

Пример 1

определить пустой неизменяемый набор

Код ссылки

scala> val a = Set[Int]()
a: scala.collection.immutable.Set[Int] = Set()

Пример 2

Определите неизменяемый набор, содержащий следующие элементы: 1,1,3,2,4,8.

Код ссылки

scala> val a = Set(1,1,3,2,4,8)
a: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 8, 4)

14.1.2 Основные операции

  • Получить размер набора (size)
  • пройтись по множеству (和遍历数组一致)
  • Добавьте элемент, в результате чего появится Set (+)
  • Объедините два набора, чтобы создать набор (++)
  • Объединить наборы и списки для создания набора (++)

Пример


  1. Создайте набор со следующими элементами: 1,1,2,3,4,5
  2. Получить размер набора
  3. Итерировать по набору, печатая каждый элемент
  4. удалить элемент 1, создать новый набор
  5. Склеить еще один набор (6, 7, 8)
  6. объединить список (6,7,8,9)

Код ссылки

// 创建集
scala> val a = Set(1,1,2,3,4,5)
a: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)

// 获取集的大小
scala> a.size
res0: Int = 5

// 遍历集
scala> for(i <- a) println(i)

// 删除一个元素
scala> a - 1
res5: scala.collection.immutable.Set[Int] = Set(5, 2, 3, 4)

// 拼接两个集
scala> a ++ Set(6,7,8)
res2: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 7, 3, 8, 4)

// 拼接集和列表
scala> a ++ List(6,7,8,9)
res6: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 9, 2, 7, 3, 8, 4)

14.2 Изменяемые множества

определение

Создать согласованный набор переменных не может изменить набор способов, но необходимо импортировать набор переменных заранее класса.

Импорт вручную:import scala.collection.mutable.Set

Пример

  1. Определите изменяемый набор со следующими элементами: 1,2,3,4
  2. Добавить элемент 5 в набор переменных
  3. удалить элемент 1 из изменяемого набора

Код ссылки

scala> val a = Set(1,2,3,4)
a: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4)                          

// 添加元素
scala> a += 5
res25: a.type = Set(1, 5, 2, 3, 4)

// 删除元素
scala> a -= 1
res26: a.type = Set(5, 2, 3, 4)

15. Отображение

Карту можно назвать картографией. Это набор пар ключ-значение. В scala карта также делится на неизменяемую карту и изменяемую карту.

15.1 Неизменяемые карты

определение

грамматика

val/var map = Map(键->值, 键->值, 键->值...)	// 推荐,可读性更好
val/var map = Map((键, 值), (键, 值), (键, 值), (键, 值)...)

Пример

  1. Определите карту, содержащую следующие данные имени и возраста учащегося

    "zhangsan", 30
    "lisi", 40
    
  2. Получить возраст Чжансана

Код ссылки

scala> val map = Map("zhangsan"->30, "lisi"->40)
map: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 30, lisi -> 40)

scala> val map = Map(("zhangsan", 30), ("lisi", 30))
map: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 30, lisi -> 30)

// 根据key获取value
scala> map("zhangsan")
res10: Int = 30

15.2 Изменяемые карты

определение

Синтаксис определения совместим с неизменяемыми картами. Но определение изменяемой карты требует ручного импортаimport scala.collection.mutable.Map

Пример

  1. Определите карту, содержащую следующие данные имени и возраста учащегося

    "zhangsan", 30
    "lisi", 40
    
  2. Измените возраст Чжансана на 20.

scala> val map = Map("zhangsan"->30, "lisi"->40)
map: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30)

// 修改value
scala> map("zhangsan") = 20

15.3 Основные операции с картой

Основная операция

  • получить значение (map(key))
  • Получить все ключи (map.keys)
  • получить все значения (map.values)
  • перебирать коллекцию карт
  • getOrElse
  • Добавить ключ, пара значений
  • удалить ключ

Пример

  1. Определите карту, содержащую следующие данные имени и возраста учащегося

    "zhangsan", 30
    "lisi", 40
    
  2. Получить возраст Чжансана

  3. Получить все имена учеников

  4. Получить все студенческие возрасты

  5. Распечатайте все имена и возраст учащихся

  6. Получить возраст вангву, если вангву не существует, вернуть -1

  7. Добавить нового ученика: ванву, 35 лет

  8. удалить lisi из изменяемой карты

Код ссылки

scala> val map = Map("zhangsan"->30, "lisi"->40)
map: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30)

// 获取zhagnsan的年龄
scala> map("zhangsan")
res10: Int = 30

// 获取所有的学生姓名
scala> map.keys
res13: Iterable[String] = Set(lisi, zhangsan)

// 获取所有的学生年龄
scala> map.values
res14: Iterable[Int] = HashMap(40, 30)

// 打印所有的学生姓名和年龄
scala> for((x,y) <- map) println(s"$x $y")
lisi 40
zhangsan 30

// 获取wangwu的年龄,如果wangwu不存在,则返回-1
scala> map.getOrElse("wangwu", -1)
res17: Int = -1

// 新增一个学生:wangwu, 35
scala> map + "wangwu"->35
res22: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30, wangwu -> 35)

// 将lisi从可变映射中移除
scala> map - "lisi"
res23: scala.collection.mutable.Map[String,Int] = Map(zhangsan -> 30)

16. итератор итератор

Scala предоставляет итератор для каждого типа коллекции для итеративного доступа к коллекции.

Обход коллекции с помощью итераторов

  • использоватьiteratorметод получения итератора из коллекции
  • Две основные операции итераторов
    • hasNext - Запрос, есть ли следующий элемент в контейнере
    • next — возвращает следующий элемент итератора, если такового нет, выбрасывает NoSuchElementException
  • Каждый итератор имеет состояние
    • Сохраняйте положение последнего элемента после итерации
    • Выдает NoSuchElementException при повторном использовании
  • Вы можете использовать while или for, чтобы возвращать элементы один за другим.

Пример

  1. Определите список со следующими элементами: 1,2,3,4,5
  2. Используя цикл while и итератор, пройдите и распечатайте список

Код ссылки

scala> val ite = a.iterator
ite: Iterator[Int] = non-empty iterator

scala> while(ite.hasNext) {
     | println(ite.next)
     | }

Пример

  1. Определите список со следующими элементами: 1,2,3,4,5
  2. Используя для выражений и итераторов, повторите и распечатайте список

Код ссылки

scala> val a = List(1,2,3,4,5)
a: List[Int] = List(1, 2, 3, 4, 5)

scala> for(i <- a) println(i)

17. Функциональное программирование

В будущем мы будем использовать функциональное программирование в большом количестве бизнес-кодов, использующих Spark/Flink. Следующие операции находятся в центре внимания обучения.

  • траверс (foreach)
  • карта (map)
  • выравнивание карты (flatmap)
  • фильтр(filter)
  • он существует(exists)
  • Сортировать(sorted,sortBy,sortWith)
  • группировка (groupBy)
  • Совокупный расчет (reduce)
  • складывать(fold)

17.1 Обход |

Ранее вы научились использовать выражение for для перебора коллекции. Далее мы изучим функциональное программирование в scala, используяforeachметод обхода и итерации. Это может сделать код более кратким.

сигнатура метода

foreach(f: (A) ⇒ Unit): Unit

инструкция

foreach API инструкция
параметр f: (A) ⇒ Единица получить функциональный объект
Входным параметром функции является элемент коллекции, а возвращаемое значение пусто.
возвращаемое значение Unit нулевой

процесс выполнения foreach

1556694050876

Пример

Существует список со следующими элементами 1,2,3,4, используйте метод foreach для повторения и печати каждого элемента

Код ссылки

// 定义一个列表
scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

// 迭代打印
scala> a.foreach((x:Int)=>println(x))

17.2 Упрощение определений функций с помощью вывода типа

Приведенное выше определение функции case немного многословно, у нас есть более краткий способ написать его. Поскольку при использовании foreach для перебора списка определяется тип каждого элемента в списке.

  • Scala может автоматически определять тип каждого параметра элемента в коллекции.
  • При создании функции можно не указывать тип списка ее параметров.

Пример

  1. Существует список со следующими элементами 1,2,3,4, используйте метод foreach для повторения и печати каждого элемента
  2. Упростите определения функций с помощью вывода типов

Код ссылки

scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

// 省略参数类型
scala> a.foreach(x=>println(x))

17.3 Использование подчеркивания для упрощения определения функций

Когда параметр функции появляется только один раз в теле функции, а тело функции не имеет вложенных вызовов, вы можете использовать символы подчеркивания для упрощения определения функции.

Пример

  1. Существует список со следующими элементами 1,2,3,4, используйте метод foreach для повторения и печати каждого элемента
  2. Использовать подчеркивание упрощенного определения функции

Код ссылки

scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

a.foreach(println(_))
  • Если параметр метода является функцией, если есть подчеркивание, компилятор scala автоматически инкапсулирует код в функцию.
  • Список параметров также автоматически обрабатывается компилятором scala.

17.4 Карта |карта

Операция сопоставления наборов — наиболее часто используемая операция при написании Spark/Flink в будущем, и мы должны освоить ее. Потому что когда выполняется вычисление данных, это процесс преобразования одного типа данных в другой тип данных.

Метод карты принимает функцию, применяет функцию к каждому элементу и возвращает новый список.

1556676981221

использование

сигнатура метода


def map[B](f: (A) ⇒ B): TraversableOnce[B]

Разбор метода

метод карты API инструкция
Дженерики [B] Определяет универсальную коллекцию, которую в конечном итоге возвращает метод карты.
параметр ж: (А) ⇒ В Передать объект функции
Функция принимает тип A (элемент списка для преобразования) и возвращает значение типа B.
возвращаемое значение TraversableOnce[B] Коллекция типа Б

анализ метода карты

1556676867764

Дело номер один

  1. Создайте список с элементами 1,2,3,4

  2. Добавьте 1 к каждому элементу в списке

Код ссылки

scala> a.map(x=>x+1)
res4: List[Int] = List(2, 3, 4, 5)

Случай 2

  1. Создайте список с элементами 1,2,3,4

  2. Используйте подчеркивание, чтобы определить функцию, которая добавляет 1 к каждому элементу в списке.

Код ссылки

scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)

scala> a.map(_ + 1)

17.5 Плоская карта |

Сглаживание отображения также является операцией, которая будет часто использоваться в будущем и должна быть освоена.

определение

FlatMap можно сначала понять как карту, а затем сгладить

1556695507696

  • карта это списокЭлементы преобразуются в список
  • сгладить, затем сгладить весь список

сигнатура метода

def flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): TraversableOnce[B]

Разбор метода

метод плоской карты API инструкция
Дженерики [B] Конечный тип элемента коллекции для преобразования
параметр f: (A) ⇒ GenTraversableOnce[B] Передать объект функции
Аргументами функции являются элементы коллекции
Возвращаемое значение функции представляет собой коллекцию
возвращаемое значение TraversableOnce[B] Коллекция типа Б

кейс

Описание случая

  1. Есть список из нескольких строк текста: «hadoop hive spark flink flume», «kudu hbase scoop storm».
  2. Получите каждое слово в текстовой строке и поместите каждое слово в список

Анализ мыслей

1556697002057

шаг

  1. Используйте карту для разделения строк текста на массивы
  2. Сгладить массив

Код ссылки

// 定义文本行列表
scala> val a = List("hadoop hive spark flink flume", "kudu hbase sqoop storm")
a: List[String] = List(hadoop hive spark flink flume, kudu hbase sqoop storm)

// 使用map将文本行转换为单词数组
scala> a.map(x=>x.split(" "))
res5: List[Array[String]] = List(Array(hadoop, hive, spark, flink, flume), Array(kudu, hbase, sqoop, storm))

// 扁平化,将数组中的
scala> a.map(x=>x.split(" ")).flatten
res6: List[String] = List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)

Упрощение операций с помощью flatMap

Код ссылки

scala>  val a = List("hadoop hive spark flink flume", "kudu hbase sqoop storm")
a: List[String] = List(hadoop hive spark flink flume, kudu hbase sqoop storm)

scala> a.flatMap(_.split(" "))
res7: List[String] = List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)

17.6 Фильтр|фильтр

Фильтрующие элементы, отвечающие определенным условиям

1556697437798

определение

сигнатура метода

def filter(p: (A) ⇒ Boolean): TraversableOnce[A]

Разбор метода

метод фильтрации API инструкция
параметр p: (A) ⇒ логическое значение Передать объект функции
Получает параметр коллекции типов
Возвращает логический тип, true, если условие выполнено, false, если нет
возвращаемое значение TraversableOnce[A] список

1556697512112

кейс

  1. Есть список номеров с элементами: 1,2,3,4,5,6,7,8,9

  2. Пожалуйста, отфильтруйте все четные числа

Код ссылки


scala> List(1,2,3,4,5,6,7,8,9).filter(_ % 2 == 0)
res8: List[Int] = List(2, 4, 6, 8)

17.7 Сортировка

В коллекциях scala вы можете использовать следующие способы сортировки.

  • сортировка по умолчанию
  • sortBy указывает поле для сортировки
  • sortС пользовательским заказом

17.7.1 Сортировка по умолчанию |

Пример

  1. Определите список со следующими элементами: 3, 1, 2, 9, 7
  2. Отсортировать список в порядке возрастания

Код ссылки

scala> List(3,1,2,9,7).sorted
res16: List[Int] = List(1, 2, 3, 7, 9)

17.7.2 Указание сортировки полей | sortBy

После конвертации по входящей функции сортируется


**подпись метода**
def sortBy[B](f: (A) ⇒ B): List[A]

Разбор метода

Метод sortBy API инструкция
Дженерики [B] Сортировать по типу
параметр ж: (А) ⇒ В Передать объект функции
Получает параметр элемента типа коллекции
Возвращает элементы типа B для сортировки
возвращаемое значение List[A] вернуть отсортированный список

Пример

  1. Есть список с несколькими строками текста: "01 хадуп", "02 флюм", "03 улей", "04 искра"
  2. Пожалуйста, отсортируйте по алфавиту

Код ссылки

scala> val a = List("01 hadoop", "02 flume", "03 hive", "04 spark")
a: List[String] = List(01 hadoop, 02 flume, 03 hive, 04 spark)

// 获取单词字段
scala> a.sortBy(_.split(" ")(1))
res8: List[String] = List(02 flume, 01 hadoop, 03 hive, 04 spark)

17.7.3 Пользовательская сортировка |

Пользовательская сортировка, пользовательская сортировка на основе функции


сигнатура метода

def sortWith(lt: (A, A) ⇒ Boolean): List[A]

Разбор метода

Метод sortWith API инструкция
параметр lt: (A, A) ⇒ логическое значение Передайте объект функции, который сравнивает размер
Получает параметры элемента двух типов коллекций
Возвращает размер двух элементов, меньше истинного, больше ложного
возвращаемое значение List[A] вернуть отсортированный список

Пример

  1. Есть список со следующими элементами: 2,3,1,6,4,5
  2. Отсортировать список по убыванию с помощью sortWith

Код ссылки

scala> val a = List(2,3,1,6,4,5)
a: List[Int] = List(2, 3, 1, 6, 4, 5)

scala> a.sortWith((x,y) => if(x<y)true else false)
res15: List[Int] = List(1, 2, 3, 4, 5, 6)

scala> res15.reverse
res18: List[Int] = List(6, 5, 4, 3, 2, 1)

Используйте подчеркивание, чтобы сократить указанный выше случай.

Код ссылки

scala> val a = List(2,3,1,6,4,5)
a: List[Int] = List(2, 3, 1, 6, 4, 5)

// 函数参数只在函数中出现一次,可以使用下划线代替
scala> a.sortWith(_ < _).reverse
res19: List[Int] = List(6, 5, 4, 3, 2, 1)

17.8 Группировка |

. Если мы хотим выполнить статистический анализ данных путем группировки, нам нужно использовать метод группировки.

определение

groupBy означает разделить список на разные группы в соответствии с функцией

сигнатура метода

def groupBy[K](f: (A) ⇒ K): Map[K, List[A]]

Разбор метода

группаПо методу API инструкция
Дженерики [K] тип поля группировки
параметр f: (А) ⇒ К Передать объект функции
Получает параметр типа элемента коллекции
Возвращает ключ типа K, этот ключ будет использоваться для группировки, этот же ключ помещается в группу
возвращаемое значение Map[K, List[A]] Возвращает карту, K — поле группировки, а List — набор данных, соответствующий этому полю группировки.

групповой анализ процесса выполнения

1556699602910

Пример

  1. Есть список с именами и полом учеников:

    "张三", "男"
    "李四", "女"
    "王五", "男"
    
  2. Пожалуйста, сгруппируйте по полу и подсчитайте количество студентов по полу

шаг

  1. Определите список кортежей для хранения имен и пола учащихся
  2. Сгруппировать по полу
  3. Преобразуйте сгруппированную карту в список: List(("мужчина" -> 2), ("женщина" -> 1))

Код ссылки

scala> val a = List("张三"->"男", "李四"->"女", "王五"->"男")
a: List[(String, String)] = List((张三,男), (李四,女), (王五,男))

// 按照性别分组
scala> a.groupBy(_._2)
res0: scala.collection.immutable.Map[String,List[(String, String)]] = Map(男 -> List((张三,男), (王五,男)),
女 -> List((李四,女)))

// 将分组后的映射转换为性别/人数元组列表
scala> res0.map(x => x._1 -> x._2.size)
res3: scala.collection.immutable.Map[String,Int] = Map(男 -> 2, 女 -> 1)

17.9 Агрегированные операции

Агрегатные операции, которые объединяют данные из списка в один. Эта операция часто используется в статистическом анализе.

17.9.1 Агрегация | уменьшение

уменьшить означает передать список в функцию для расчета агрегации

определение


сигнатура метода

def reduce[A1 >: A](op: (A1, A1) ⇒ A1): A1

Разбор метода

метод уменьшения API инструкция
Дженерики [A1 >: A] (нижняя граница) A1 должен быть суперклассом типа элемента коллекции
параметр оп: (А1, А1) ⇒ А1 Передайте объект функции для непрерывных операций агрегирования
Первый параметр типа A1: переменная после текущей агрегации.
Второй параметр типа A1: элемент, который в данный момент должен быть агрегирован.
возвращаемое значение A1 Список, наконец, агрегируется в один элемент

сократить анализ процесса выполнения

1556700700806

[!NOTE]

  • Уменьшение и уменьшениеЛефт имеют одинаковый эффект, указывая на то, что расчет ведется слева направо.

  • reduceRight означает расчет справа налево

кейс


  1. Определите список со следующими элементами: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
  2. Вычислите сумму всех элементов, используя сокращение

Код ссылки

scala> val a = List(1,2,3,4,5,6,7,8,9,10)
a: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> a.reduce((x,y) => x + y)
res5: Int = 55

// 第一个下划线表示第一个参数,就是历史的聚合数据结果
// 第二个下划线表示第二个参数,就是当前要聚合的数据元素
scala> a.reduce(_ + _)
res53: Int = 55

// 与reduce一样,从左往右计算
scala> a.reduceLeft(_ + _)
res0: Int = 55

// 从右往左聚合计算
scala> a.reduceRight(_ + _)
res1: Int = 55

17.9.2 Сложить | сложить

fold похож на reduce, но с еще одним параметром, определяющим начальное значение

определение


сигнатура метода

def fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1

Разбор метода

метод уменьшения API инструкция
Дженерики [A1 >: A] (нижняя граница) A1 должен быть суперклассом типа элемента коллекции
параметр 1 z: A1 Первоначальный значение
параметр 2 оп: (А1, А1) ⇒ А1 Передайте функциональный объект для непрерывных операций складывания
Первый параметр типа A1: текущая свернутая переменная
Второй параметр типа A1: элемент, который в данный момент нужно свернуть.
возвращаемое значение A1 Список окончательно свернут в один элемент

[!NOTE]

  • Эффект fold и foldLet одинаков, что означает, что он рассчитывается слева направо.

  • foldRight означает расчет справа налево

кейс


  1. Определите список со следующими элементами: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
  2. Вычислить сумму всех элементов, используя метод сгиба

Код ссылки

scala> val a = List(1,2,3,4,5,6,7,8,9,10)
a: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> a.fold(0)(_ + _)
res4: Int = 155

| |Возвращаемое значение |Map[K, List[A]] |Возвращает карту, K — поле группировки, а List — набор данных, соответствующий этому полю группировки |

групповой анализ процесса выполнения

[Дамп изображения внешней ссылки...(img-9EePG3Hl-1625201993570)]

Пример

  1. Есть список с именами и полом учеников:

    "张三", "男"
    "李四", "女"
    "王五", "男"
    
  2. Пожалуйста, сгруппируйте по полу и подсчитайте количество студентов по полу

шаг

  1. Определите список кортежей для хранения имен и пола учащихся
  2. Сгруппировать по полу
  3. Преобразуйте сгруппированную карту в список: List(("мужчина" -> 2), ("женщина" -> 1))

Код ссылки

scala> val a = List("张三"->"男", "李四"->"女", "王五"->"男")
a: List[(String, String)] = List((张三,男), (李四,女), (王五,男))

// 按照性别分组
scala> a.groupBy(_._2)
res0: scala.collection.immutable.Map[String,List[(String, String)]] = Map(男 -> List((张三,男), (王五,男)),
女 -> List((李四,女)))

// 将分组后的映射转换为性别/人数元组列表
scala> res0.map(x => x._1 -> x._2.size)
res3: scala.collection.immutable.Map[String,Int] = Map(男 -> 2, 女 -> 1)

17.9 Агрегированные операции

Агрегатные операции, которые объединяют данные из списка в один. Эта операция часто используется в статистическом анализе.

17.9.1 Агрегация | уменьшение

уменьшить означает передать список в функцию для расчета агрегации

определение


сигнатура метода

def reduce[A1 >: A](op: (A1, A1) ⇒ A1): A1

Разбор метода

метод уменьшения API инструкция
Дженерики [A1 >: A] (нижняя граница) A1 должен быть суперклассом типа элемента коллекции
параметр оп: (А1, А1) ⇒ А1 Передайте объект функции для непрерывных операций агрегирования
Первый параметр типа A1: переменная после текущей агрегации.
Второй параметр типа A1: элемент, который в данный момент должен быть агрегирован.
возвращаемое значение A1 Список, наконец, агрегируется в один элемент

сократить анализ процесса выполнения

[Дамп изображения внешней ссылки...(img-w3XVlj6C-1625201993571)]

[!NOTE]

  • Уменьшение и уменьшениеЛефт имеют одинаковый эффект, указывая на то, что расчет ведется слева направо.

  • reduceRight означает расчет справа налево

кейс


  1. Определите список со следующими элементами: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
  2. Вычислите сумму всех элементов, используя сокращение

Код ссылки

scala> val a = List(1,2,3,4,5,6,7,8,9,10)
a: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> a.reduce((x,y) => x + y)
res5: Int = 55

// 第一个下划线表示第一个参数,就是历史的聚合数据结果
// 第二个下划线表示第二个参数,就是当前要聚合的数据元素
scala> a.reduce(_ + _)
res53: Int = 55

// 与reduce一样,从左往右计算
scala> a.reduceLeft(_ + _)
res0: Int = 55

// 从右往左聚合计算
scala> a.reduceRight(_ + _)
res1: Int = 55

17.9.2 Сложить | сложить

fold похож на reduce, но с еще одним параметром, определяющим начальное значение

определение


сигнатура метода

def fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1

Разбор метода

метод уменьшения API инструкция
Дженерики [A1 >: A] (нижняя граница) A1 должен быть суперклассом типа элемента коллекции
параметр 1 z: A1 Первоначальный значение
параметр 2 оп: (А1, А1) ⇒ А1 Передайте функциональный объект для непрерывных операций складывания
Первый параметр типа A1: текущая свернутая переменная
Второй параметр типа A1: элемент, который в данный момент нужно свернуть.
возвращаемое значение A1 Список окончательно свернут в один элемент

[!NOTE]

  • Эффект fold и foldLet одинаков, что означает, что он рассчитывается слева направо.

  • foldRight означает расчет справа налево

кейс


  1. Определите список со следующими элементами: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
  2. Вычислить сумму всех элементов, используя метод сгиба

Код ссылки

scala> val a = List(1,2,3,4,5,6,7,8,9,10)
a: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> a.fold(0)(_ + _)
res4: Int = 155