1. Higher-order functions

    Function arguments contain function types or return values contain function types

    public inline fun IntArray.forEach(action: (Int) - >Unit): Unit {
        for (element in this) action(element)
    }
    Copy the code
    // Sample code
    intArrayOf(1.1).map{"value = $it"}.forEach(::print)
    
    // Implement it
    // transform function type :(Int) -> String
    public inline fun <R> IntArray.map(transform: (Int) - >R): List<R> {
        return mapTo(ArrayList<R>(size), transform)
    }
    
    // the mapTo function converts an Int array to a String array
    public inline fun <R, C : MutableCollection<in R>> IntArray.mapTo(destination: C, transform: (Int) - >R): C {
        for (item in this)
            destination.add(transform(item))
        return destination
    }
    Copy the code
  2. Inline function

    The inline keyword is used, usually for higher-order functions, to replace the lambda expression with the actual code, avoiding object creation

    intArrayOf(1.1).map{"value = $it"}.forEach(::print)
    Copy the code

    Decompile Tools->Kotlin->Show Kotlin ByteCode ->Decompile

    // The actual code
    int[] $this$map$iv = new int[] {1.1};
    int $i$f$forEach = false;
    Collection destination$iv$iv = (Collection)(new ArrayList($this$map$iv.length));
    int $i$f$mapTo = false;
    int[] var5 = $this$map$iv;
    int var6 = $this$map$iv.length;
    
    // recreate the collection
    for(int var7 = 0; var7 < var6; ++var7) {
       int item$iv$iv = var5[var7];
       int var10 = false;
       String var12 = "value = " + item$iv$iv;
       destination$iv$iv.add(var12);
    }
    
    Iterable $this$forEach$iv = (Iterable)((List)destination$iv$iv);
    $i$f$forEach = false;
    Iterator var2 = $this$forEach$iv.iterator();
    
    // Iterate through the collection and print
    while(var2.hasNext()) {
       Object element$iv = var2.next();
       int var15 = false;
       boolean var16 = false;
       System.out.print(element$iv);
    }
    Copy the code
    1. local return

      intArrayOf(1.2.3).forEach {
          if (it == 1)
          	// forEach ends when element ==1
              return@forEach
          println(it)
      }
      
      // The equivalent of the above:
      val intArrayOf = intArrayOf(1.2.3)
      for (element in intArrayOf) {
          if (element == 1) continue
          print(element)
      }
      Copy the code
    2. non-local return

      InlineTest {println("") return main return} println("main end") inline fun inlineTest(block1: () -> Unit) { block1() }Copy the code
    3. noinline

      Noinline is used when inline functions have multiple function arguments and a function argument does not need to be inline

    4. crossinline

      Since there are both local and non-local returns inline, the following case is misleading

      fun main(a) {
          inlineTest {
              println("")
              return
          }
          println("main end")}inline fun inlineTest(block1: () -> Unit) {
          thread {
          	// Compile error
              block1()
          }
      }
      Copy the code

      Processing method

      fun main(a) {
          inlineTest {
              println("")
              // local return
              return@inlineTest
          }
          println("main end")}// Add crossinline keyword
      inline fun inlineTest(crossinline block1: () -> Unit) {
          thread {
              block1()
          }
      }
      Copy the code
  3. let run also apply use

    1. let run

      The last line of non-assignment code is the return value of the closure, otherwise Unit is returned.

    2. also apply

      Returns the current object

    3. Use Automatically shuts down resources

      File("ktpractice.iml").inputStream().reader().buffered()
          .use {
              var line: String
              while(it.readLine().also { line = it } ! =null) {
                  println(line)
              }
          }
      Copy the code
  4. Set transformations and sequences

    1. The filter to filter

    2. The map mapping

    3. FlatMap transform

      Elements map to collections and concatenate collections into new collections

    4. sum

    5. reduce

      fun main(a) {
          val list = arrayListOf(1.2.3.4)
          val reduce = list.reduce { acc, i ->
              acc + i
          }
          println(reduce)
      }
      
      / / output 10
      Copy the code
    6. Fold initial value and concatenation operation

      fun main(a) {
          val list = arrayListOf(1.2.3.4)
          val fold = list.foldRight(StringBuilder()) { i, acc ->
              acc.append(i)
          }
          println(fold)
      }
      
      / / output 4321
      Copy the code
    7. A lazy sequence

      val list = arrayListOf(1.2.3.4)
      val map = list.filter {
          print("$it    ")
          it % 2= =0
      }.map {
          print("$it    ")
          it + 1
      }
      println("result: $map")
      
      / / output
      filter: 1    
      filter: 2    
      filter: 3    
      filter: 4    
      map: 2    
      map: 4    
      result: [3.5]
      Copy the code

      AsSequence () is much lazier than the above

      fun main(a) {
          val list = arrayListOf(1.2.3.4)
          val map = list.asSequence().filter {
              print("$it    ")
              it % 2= =0
          }.map {
              print("$it    ")
              it + 1
          }
          println("result: $map")}// Print the map address,
      Copy the code

      The result is generated only when a Terminal operator is encountered

      fun main(a) {
          val list = arrayListOf(1.2.3.4)
          list.asSequence().filter {
              println("filter: $it    ")
              it % 2= =0
          }.map {
              println("map: $it    ")
              it + 1
          }.forEach(::println)
      }
      
      / / output:
      filter: 1    
      filter: 2    
      map: 2    
      3
      filter: 3    
      filter: 4    
      map: 4    
      5
      Copy the code
  5. SAM(Single abstract Method) transformation

    Kotlin vs. java8’s SAM transformation

  6. case

    1. Count characters

      File("ktpractice.iml").readText().toCharArray()
          .filterNot(Char::isWhitespace)
          .groupBy { it }
          .map { it.key to it.value.size }
          .sortedByDescending { it.second }
          .forEach(::println)
      Copy the code
    2. HTML DSL

      public class WeekQuery  {
      
          private static final String TIME_TEMPLATE = "(day between '%s' and '%s')";
      
          private int mYear;
          private int mWeek;
      
          public WeekQuery(int year, int week) {
              mYear = year;
              mWeek = week;
          }
      
          public String getWhereClause(a) {
              LocalDate firstMondayOfYear = Stream.iterate(LocalDate.of(mYear, 1.1), date -> date.plusDays(1))
                      .limit(7)
                      .filter(date -> date.getDayOfWeek() == DayOfWeek.MONDAY)
                      .collect(Collectors.toList())
                      .get(0);
              LocalDate destMondayOfYear = firstMondayOfYear.plusWeeks(mWeek - 1);
              return String.format(TIME_TEMPLATE, destMondayOfYear, destMondayOfYear.plusDays(6));
          }
      
          public static void main(String[] args) {
              for (int i = 1; i < 55; i++) {
                  WeekQuery weekQuery = new WeekQuery(2018, i);
                  System.out.println(i + "Week" + weekQuery.getWhereClause());
              }
              showWeeks(1.55);
          }
      
          public static void showWeeks(int initWeek, int weeks) {
              LocalDate initData = LocalDate.of(2018.1.1).plusWeeks(initWeek - 1);
              Stream.iterate(initData, date -> date.plusDays(7))
                      .limit(weeks)
                      .map(day -> day + "~" + day.plusDays(6)).forEach(System.out::println); }}Copy the code