scala快速入门02

scala从入门开始02

1.函数简写

  • sortby
val arr = Array(1,5,3,10,2,4,6,9)

scala> arr.sorted
res17: Array[Int] = Array(1, 2, 3, 4, 5, 6, 9, 10)

scala> arr.sortWith((x,y)=>x>y)
res18: Array[Int] = Array(10, 9, 6, 5, 4, 3, 2, 1)

scala> arr.sortWith((x,y)=>x>7)
res19: Array[Int] = Array(9, 10, 1, 5, 3, 2, 4, 6)

val arr2 = Array(1,11,15,2,5,22,27,3,5,6)
// sortBy内是排序规则,不会更改数组内元素的数据类型。
scala> arr2.sortBy(x => x + "")
res22: Array[Int] = Array(1, 11, 15, 2, 22, 27, 3, 5, 5, 6)

2.方法转换函数

// 定义个方法
def m2(x: Int, y:Double): Double = x * y
// 赋值变量
val f2 = m2 _
// 此时f2相当于一个函数,直接调用
f2(4,3.0)
res27: Double = 12.0

  • 看下面示例
val arr = Array(1,2,3,4,5)
scala> def m(x:Int):Int = x * x
m: (x: Int)Int

scala> arr.map(m)
res30: Array[Int] = Array(1, 4, 9, 16, 25)


// 为什么方法也可以当参数进行传入,这是由于内部实现语法糖,将方法转换成函数 相当于 arr.map(m _)

3.reduce和reduceLeft

  • reduce:

    • 示例:
    val arr = Array(1,2,3,4,5,6,7)
    // 计算arr的和
    val r = arr.reduce((x, y) => x + y)
    // 简写方式:
    val r2 = arr.reduce(_ + _)
    
  • reduceLeft

    • reduce 底层调的是reduceLeft
     val r3 = arr.reduceLeft(_ + _)
     println(r3)
    

4.fold和foldLeft

  • 叠加操作

    • 示例:
    val lst = List(1,2,3,4,5)
    val f1 = lst.fold(0)(_+_)
    val f2 = lst.foldLeft(0)(_+_)
    println(f1)
    println(f2)
    
    • fold可以指定一个初始值,上面示例指定初始值为0

5.aggregate

  • 它可以并行话集合,并行多个线程。

    val lst:List[List[Int]] = List(List(1,2,3), List(4,5,6), List(7,8,9))
    lst.aggregate(0)(_ + _.sum, _ + _)
    // _+_.sum 计算第一个List  6
    // _+_.sum 计算第二个List  15
    // _+_.sum 计算第三个List  24
    // 当第一个List计算出来的时候就放到  _+_   初始值为0 + 6 
    // 当第二个List计算出来的时候就放到  _+_   初始值为6 + 15
    // 当第三个List计算出来的时候就放到  _+_   初始值为21 + 24
    
  • 并行集合,充分利用计算机资源:

    scala> val arr = Array(1,2,3,4,5,6,7,8,9,10)
    arr: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    // par并行化集合
    scala> arr.par
    res35: scala.collection.parallel.mutable.ParArray[Int] = ParArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    
    • 它可以将lst并行编程一个可以多线程同时运算的并行化集合
    var r = lst.par.aggregate(0)(_ + _.sum, _+_)
    print(r)
    

6.foreach

  • 循环
val lst = List("Haddop", "Spark", "Flink", "Hbase")
nLst.foreach(w => println(w))

7.UpperCase和LowerCase

  • UpperCase转大写,LowerCase转小写
val lst = List("Haddop", "Spark", "Flink", "Hbase")
val nLst = lst.map(_.toUpperCase)
val lLst = lst.map(_.toLowerCase)

8.Java实现参数为方法传入将单词转大写

  • 通过接口实现:
// MyListTest.java
package cn._xjk;

import java.util.Arrays;
import java.util.List;

public class MyListTest {
    public static void main(String[] args) {
        List<String> words = Arrays.asList(new String[]{"Haddop", "Spark", "Flink", "Hbase"});
        
        MyList myList = new MyList(words);
        // 扩展的map方法传入逻辑: 传入接口
        List<String> nLst = myList.map(new MapFunction() {
            @Override
            public String call(String word) {
                return word.toUpperCase();
            }
        });

        for (String w: nLst
             ) {
            System.out.println(w);
        }
    }
}

// MyList.java
package cn._xjk;

import java.util.ArrayList;
import java.util.List;

public class MyList {
    private List<String> oldList;
    public MyList(List<String> words) {
        this.oldList = words;
    }
    public List<String> map(MapFunction func) {
        List<String> nList = new ArrayList<>();
        for(String oldword: oldList){
            // 计算逻辑
            String nWord = func.call(oldword);
            // 将新的单词保存在新的集合中
            nList.add(nWord);
        }
        return nList;
    }
}

// MapFunction 
// 规范接口传入,输出数据类型
package cn._xjk;

public interface MapFunction {
    // 要求传入String类型, 返回String类型
    String call(String word);
}

java中使用函数式编程

  • 1.自行封装后可以使用链式编程,使用泛型方式
// MyAdvListTest.java
package cn._xjk.adv;
import java.util.List;
public class MyAdvListTest {
    public static void main(String[] args) {
        MyAdvList<String> myAdvList = new MyAdvList<>();
        myAdvList.add("Hadoop");
        myAdvList.add("Spark");
        myAdvList.add("Flink");
        myAdvList.add("Hbase");
        // map
        List<String> nList = myAdvList.map(w -> w.toUpperCase()).map(w -> w.toLowerCase() + "2.0");
        for (String s: nList){
            System.out.println(s);
        }
        // filter
        List<String> nList2 = myAdvList.map(w -> w.toUpperCase()).filter(new MyFunction1<String, Boolean>() {
            @Override
            public Boolean call(String s) {
                return s.startsWith("H");
            }
        });
        for (String s: nList2){
            System.out.println(s);
        }
    }
}

// MyFunction1.java
package cn._xjk.adv;
// T输入类型
// R返回类型
public interface MyFunction1<T, R> {
    R call(T t);
}

// MyTraversableLike.java
package cn._xjk.adv;
import java.util.List;
public interface MyTraversableLike<T> {
    /*
    * 泛型方法,如果方法有未定义泛型,需要在返回值或void前面加上<R>
    * */
    <R> List<R> map(MyFunction1<T,R> func);

    List<T> filter(MyFunction1<T,Boolean> func);
}

// MyAdvList.java
package cn._xjk.adv;

import java.util.ArrayList;
import java.util.List;

/*
* 1. 集合可以传入任何类型: 使用泛型
* 2. 集合要有add,remove等List等具有的方法,还有有map,filter,reduce等方法
* */
// MyTraversableLike 为接口
public class MyAdvList<T> extends ArrayList<T> implements MyTraversableLike<T> {
    // 重写map方法
    @Override
    public <R> MyAdvList<R> map(MyFunction1<T, R> func) {
        // 创建新的List
        MyAdvList<R> nList = new MyAdvList<>();
        // 遍历老List
        for (T t: this) {
            // 应用外部传入计算逻辑
            R r = func.call(t);
            // 将返回r放入新的List中
            nList.add(r);
        }
        return nList;
    }

    @Override
    public MyAdvList<T> filter(MyFunction1<T, Boolean> func) {
        // 创建新的List
        MyAdvList<T> nList = new MyAdvList<>();
        // 遍历老List
        for (T t: this) {
            Boolean flag = func.call(t);
            // 将返回r放入新的List中
            if (flag){
                nList.add(t);
            }
        }
        return nList;
    }
}

  • 2.匿名实现类方式实现:链式编程 Java8
package cn._xjk.adv;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<String> words = Arrays.asList(new String[]{"Haddop", "Spark", "Flink", "Hbase"});
        // 在Java中,支持Lambda表达式(函数),Stream(链式编程)
        // 1.将Java集合变成stream
        Stream<String> stream = words.stream();
        // 调用filter
        Stream<String> result = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("H");
            }
        }).map(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.toUpperCase() + "3.1";
            }
        });
//        result.forEach(System.out::println);
        result.forEach(w -> System.out.println(w));
    }
}

  • 3.Lambda表达式实现方式:
stream.filter(w -> w.startsWith("H")).map(w -> w.toUpperCase() + "4.0").forEach(System.out::println);

抽象类和接口方法

  • 接口可以有抽象也可以有实现,它内部定义一个标准。
  • Java中类只支持单继承,继承了类后,可以重写父类的方法。抽象类

xx.练习

  • 转大小写:
package cn._xjk

object FunctionTest {
  def transform(func:String=>String): List[String] = {
    val lst = List("Haddop", "Spark", "Flink", "Hbase")
    val nLst = lst.map(func)
    nLst
  }
  def main(args: Array[String]): Unit = {
    val f = (s: String) => s.toUpperCase()
    val nLst = transform(f)
    nLst.foreach(w => println(w))
  }
}

原文地址:https://www.cnblogs.com/xujunkai/p/14413168.html