欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Scala中Array和List的區(qū)別說明

 更新時(shí)間:2021年10月11日 09:00:59   作者:power0405hf  
這篇文章主要介紹了Scala中Array和List的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Scala Array和List的區(qū)別

Difference between Array and List in scala

Q:什么時(shí)候用Array(Buffer)和List(Buffer)?

A:Scala中的List是不可變的遞歸數(shù)據(jù)(immutable recursive data),是Scala中的一種基礎(chǔ)結(jié)構(gòu),你應(yīng)該多用List而不是Array(Array實(shí)際上是mutable,不可變(immutable)的Array是IndexedSeq)

Mutable Structures

ListBuffer提供一個(gè)常數(shù)時(shí)間的轉(zhuǎn)換到List。

一個(gè)Scala的Array應(yīng)該是由Java array生成的,因此一個(gè)Array[Int]也許比List[Int]更有效率。

但是,我認(rèn)為Scala中數(shù)組盡量少用,因?yàn)樗杏X是你真的需要知道底層發(fā)生了什么,來決定是否Array將所需的基本數(shù)據(jù)類型進(jìn)行備份,或者可能boxed as a wrapper type.

Performance differences Array List
Access the ith element O(1) O(i)
Discard the ith element O(n) O(i)
Insert an element at i O(n) O(i)
Reverse O(n) O(n)
Concatenate (length m,n) O(n+m) O(n)
Calculate the length O(1) O(n)
memory differences Array List
Get the first i elements O(i) O(i)
Drop the first i elements O(n-i) O(1)
Insert an element at i O(n) O(i)
Reverse O(n) O(n)
Concatenate (length m,n) O(n+m) O(n)

所以,除非你需要快速隨機(jī)訪問或需要count batches of elements,否則,列表比數(shù)組更好。

Scala快排List和Array數(shù)組效率實(shí)測(cè)

代碼

package com.tingfeng.scala.test
import scala.annotation.tailrec
import scala.util.{Random, Sorting}
/**
  * 快速排序測(cè)試
  */
object SortTest {
  /**
    * 初始化一個(gè)數(shù)組,產(chǎn)生隨機(jī)數(shù)字填充
    * @param size
    * @return
    */
  def initRandomList(size :Int):List[Int]={
    val random = new Random()
    def initList(size :Int,random: Random):List[Int] = size match {
      case 0 => Nil
      case 1 => List(random.nextInt())
      case s:Int =>
        val value = s / 2
        if( s % 2 == 0) {
          initList(value,random) ++ initList(value,random)
        }else{
          initList(value,random) ++ initList(value + 1,random)
        }
    }
    initList(size,random)
  }
  /**
    * 打印出使用的時(shí)間
    * @param call
    */
  def printTime(call : => Unit,tag: String = ""){
    val startTime = System.currentTimeMillis()
    println(tag)
    call
    println
    println(s"use time : ${System.currentTimeMillis() - startTime}\n")
  }
  /**
    * 交換數(shù)組中兩個(gè)位置的值,經(jīng)過測(cè)試這種按位與的方式比普通建立變量交換的效率更高
    * @param array
    * @param x
    * @param y
    */
  def swap(array: Array[Int],x:Int,y:Int):Unit ={
      val t = array(x) ^ array(y)
      array(x) = t ^ array(x)
      array(y) = t ^ array(y)
  }
  /**
    * 將傳入的值直接返回,并且執(zhí)行邏輯
    * @param call
    * @param any
    * @tparam A
    */
  def doThing[A<:Any](any: A,call: A => Unit):A = {
      call(any)
      any
  }
  /**
    * 打印列表
    */
  def printList[A<%Seq[Any]](seq:A,size :Int = 10):Unit={
    seq.splitAt(size)._1.foreach(it => print(s"$it,"))
  }
  def shuffleIntSeq(seq: Array[Int],size: Int):Unit={
      val random = new Random()
      val maxSize = size/2
      for(i <- 0 to maxSize){
          swap(seq,i,maxSize + random.nextInt(maxSize))
      }
  }
  def main(args: Array[String]): Unit = {
    val size = 5000000
    val printSize = 10
    val list = initRandomList(size)
    //打印出錢100個(gè),和List快速排序的時(shí)間花費(fèi)
    printTime(printList[List[Int]](qSortList(list),Math.min(10,size)),"qSortList")
    val array = list.toArray
    printTime(printList[Array[Int]](doThing[Array[Int]](array,Sorting.quickSort),Math.min(printSize,size)),"Sorting.quickSort")
    shuffleIntSeq(array,size)
    printTime(printList[Array[Int]](doThing[Array[Int]](array,qSortArray1),Math.min(printSize,size)),"qSortArray1")
    shuffleIntSeq(array,size)
    printTime(printList[Array[Int]](doThing[Array[Int]](array,qSortArray2),Math.min(printSize,size)),"qSortArray2")
    shuffleIntSeq(array,size)
    printTime(printList[Array[Int]](doThing[Array[Int]](array,qSortArray3),Math.min(printSize,size)),"qSortArray3")
    shuffleIntSeq(array,size)
    printTime(printList[Array[Int]](doThing[Array[Int]](array,qSortArray4),Math.min(printSize,size)),"qSortArray4")
  }
  /**
    * 對(duì)List快速排序
    * @param list
    * @return
    */
  def qSortList(list: List[Int]):List[Int] = list match {
    case Nil => Nil
    case head :: other =>
      val (left, right) = other.partition(_ < head)
      (qSortList(left) :+ head) ++ qSortList(right)
  }
  /**
    * 通過每次比較數(shù)組‘head'值與其余值的方式直接實(shí)現(xiàn)
    * 比‘head'小的值移動(dòng)到其前,比‘head'大的移動(dòng)到其之后
    * @param array
    */
  def qSortArray1(array: Array[Int]):Unit = {
    def sort(ay : Array[Int],start: Int,end: Int):Unit={
      if(start >= end) {
        return
      }
      val head = ay(start)
      var spliteIndex = start
      for (i <- start + 1 to end){
        if(ay(i) < head){
          swap(array,spliteIndex,i)
          spliteIndex += 1
        }
      }
      if(start != spliteIndex){
        sort(ay, start, spliteIndex)
      }
      if(start == spliteIndex){
        spliteIndex += 1
      }
      if(spliteIndex != end){
        sort(ay, spliteIndex, end)
      }
    }
    sort(array,0,array.size - 1)
  }
  /**
    * 將數(shù)據(jù)以中線拆分左右兩部分,交換值,使得右邊值比左邊大,
    * 再以左或者右邊交換的界限分為兩部分做遞歸
    * @param array
    */
  def qSortArray2(array: Array[Int]) {
    def sort(l: Int, r: Int) {
      val pivot = array((l + r) / 2)
      var lv = l; var rv = r
      while (lv <= rv) {
        while (array(lv) < pivot) lv += 1
        while (array(rv) > pivot) rv -= 1
        if (lv <= rv) {
          swap(array,lv, rv)
          lv += 1
          rv -= 1
        }
      }
      if (l < rv) sort(l, rv)
      if (rv < r) sort(lv, r)
    }
    sort(0, array.length - 1)
  }
  /**
    * 系統(tǒng)自帶的過濾函數(shù),無法排序成功,因?yàn)閒ilter返回的是引用
    * @param xs
    * @return
    */
  def qSortArray3(xs: Array[Int]): Array[Int] ={
    if (xs.length <= 1){
      xs
    }else {
      val pivot = xs(xs.length / 2)
      val left = xs filter (pivot > _)
      val cu = xs filter (pivot == _ )
      val right = xs filter (pivot < _ )
      Array.concat(
        qSortArray3(left),cu,qSortArray3(right))
    }
  }
  /**
    * 系統(tǒng)自帶的分割函數(shù),無法排序成功,因?yàn)閜artition返回的是引用,數(shù)據(jù)量大的時(shí)候會(huì)棧溢出失敗
    * @param xs
    * @return
    */
  def qSortArray4(array: Array[Int]): Array[Int] ={
    if (array.length <= 1){
      array
    }else {
      val head = array(0)
      val (left,right) = array.tail partition  (_ < head )
      Array.concat(qSortArray4(left),Array(head),qSortArray4(right))
    }
  }
}

測(cè)試結(jié)果

qSortList
-2147483293,-2147483096,-2147481318,-2147480959,-2147479572,-2147479284,-2147478285,-2147477579,-2147476191,-2147475936,
use time : 28808

Sorting.quickSort
-2147483293,-2147483096,-2147481318,-2147480959,-2147479572,-2147479284,-2147478285,-2147477579,-2147476191,-2147475936,
use time : 773

qSortArray1
-2147483293,-2147483096,-2147481318,-2147480959,-2147479572,-2147479284,-2147478285,-2147477579,-2147476191,-2147475936,
use time : 1335

qSortArray2
-2147483293,-2147483096,-2147481318,-2147480959,-2147479572,-2147479284,-2147478285,-2147477579,-2147476191,-2147475936,
use time : 629

qSortArray3
508128328,554399267,876118465,968407914,1274954088,1550124974,296879812,2125832312,1874291320,965362519,
use time : 10617

qSortArray4
865409973,-645195021,-735017922,-1893119148,1838343395,1038029591,-560471115,-182627393,-228613831,220531987,
use time : 6904


Process finished with exit code 0

環(huán)境:版本Scala2.12.6 , win10 ,ryzen5 1600 , 8G

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中for、foreach、stream區(qū)別和性能比較詳解

    Java中for、foreach、stream區(qū)別和性能比較詳解

    for、foreach、stream都可以循環(huán)處理數(shù)據(jù),如果單純當(dāng)循環(huán)使用,for、foreach、stream哪個(gè)性能更好,這篇文章主要給大家介紹了關(guān)于Java中for、foreach、stream區(qū)別和性能的相關(guān)資料,需要的朋友可以參考下
    2024-03-03
  • 基于Java中對(duì)域和靜態(tài)方法的訪問不具有多態(tài)性(實(shí)例講解)

    基于Java中對(duì)域和靜態(tài)方法的訪問不具有多態(tài)性(實(shí)例講解)

    下面小編就為大家?guī)硪黄贘ava中對(duì)域和靜態(tài)方法的訪問不具有多態(tài)性(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java中創(chuàng)建對(duì)象的6種方式

    Java中創(chuàng)建對(duì)象的6種方式

    大家好,本篇文章主要講的是Java中創(chuàng)建對(duì)象的6種方式,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下的相關(guān)資料
    2022-02-02
  • 通過jxl.jar 讀取、導(dǎo)出excel的實(shí)例代碼

    通過jxl.jar 讀取、導(dǎo)出excel的實(shí)例代碼

    通過jxl.jar 讀取、導(dǎo)出excel的實(shí)例代碼,需要的朋友可以參考一下
    2013-03-03
  • Java switch 語句如何使用 String 參數(shù)

    Java switch 語句如何使用 String 參數(shù)

    這篇文章主要介紹了Java switch 語句如何使用 String 參數(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • redis深入淺出分布式鎖實(shí)現(xiàn)下篇

    redis深入淺出分布式鎖實(shí)現(xiàn)下篇

    在單體應(yīng)用中,如果我們對(duì)共享數(shù)據(jù)不進(jìn)行加鎖操作,會(huì)出現(xiàn)數(shù)據(jù)一致性問題,我們的解決辦法通常是加鎖。下面我們一起聊聊使用redis來實(shí)現(xiàn)分布式鎖
    2022-08-08
  • SpringBoot整合Spring?Data?JPA的詳細(xì)方法

    SpringBoot整合Spring?Data?JPA的詳細(xì)方法

    JPA全稱為Java Persistence API(Java持久層API),是一個(gè)基于ORM的標(biāo)準(zhǔn)規(guī)范,在這個(gè)規(guī)范中,JPA只定義標(biāo)準(zhǔn)規(guī)則,不提供實(shí)現(xiàn),本文重點(diǎn)給大家介紹SpringBoot整合Spring?Data?JPA的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2022-02-02
  • Java最簡(jiǎn)單的DES加密算法實(shí)現(xiàn)案例

    Java最簡(jiǎn)單的DES加密算法實(shí)現(xiàn)案例

    下面小編就為大家?guī)硪黄狫ava最簡(jiǎn)單的DES加密算法實(shí)現(xiàn)案例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Spring boot實(shí)現(xiàn)上傳文件到本地服務(wù)器

    Spring boot實(shí)現(xiàn)上傳文件到本地服務(wù)器

    這篇文章主要為大家詳細(xì)介紹了Spring boot實(shí)現(xiàn)上傳文件到本地服務(wù)器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • java對(duì)圖片進(jìn)行壓縮和resize縮放的方法

    java對(duì)圖片進(jìn)行壓縮和resize縮放的方法

    本篇文章主要介紹了java對(duì)圖片進(jìn)行壓縮和resize調(diào)整的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07

最新評(píng)論