   1  |   * -+----> |  3   +   * -+--->|  NIL   |
+------+------+      +------+------+      +-------------+    +--------+
^                    ^                                           ^
|                    |                                           |
val list2            val list1                                   |
                                                                 |
                                                                 |
(copy)                                                           |
+------+------+      +------+------+    +--------+-------+       |
|   1  |   * -+----> |  3   +   * -+--->|   5    |    *--+-------+
+------+------+      +-------------+    +--------+-------+    
^
|
val list3 

It's a linear time operation because, to append to a list of length N, we have to make copies of all N cons cells (except for Nil).
As for scala's ListBuffer, its append works by directly mutating the backing list, rewriting the tail reference of the final cons cell, which has the slighly awkward looking type ::[A].
In List.scala:
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
   override def tail : List[B] = tl
   override def isEmpty: Boolean = false
}

[..]
In ArrayList.scala:
/** Appends a single element to this buffer. This operation takes constant time.
*
*  @param x  the element to append.
*  @return   this $coll.
*/
def += (x: A): this.type = {
  if (exported) copy()
  if (isEmpty) {
    last0 = new :: (x, Nil)
    start = last0
  } else {
    val last1 = last0
    last0 = new :: (x, Nil)
    last1.tl = last0
  }
  len += 1
  this
} 

last1.tl = last0 is permitted because ::.tl has visibility private[scala], permitting unsafe "under the hood" operations for mutating collections such as ListBuffer. 

A:

They are both implemented similarly to linked lists.
1   |    * -+---- > |   3    +    * -+--->|   NIL    | 
 + ------+------+       + ------+------+       + -------------+     + --------+ 
 ^                     ^                                            ^ 
 |                     |                                            | 
 val list2             val list1                                    | 
                                                                  | 
                                                                  | 
 (copy)                                                            | 
 + ------+------+       + ------+------+     + --------+-------+        | 
 |    1   |    * -+---- > |   3    +    * -+--->|    5     |     * --+-------+ 
 + ------+------+       + -------------+     + --------+-------+    
 ^ 
 | 
 val list3 

 It's a linear time operation because, to add to a tilt of distance N, we have to produce copy of all N cons cells (except for Nil). 
 As for scala's ListBuffer, its append work by directly mutating the support tilt, rewriting the tail reference book of the final cons cell, which experience the slighly awkward looking type: : [ A ]. 
 In List.scala: 
 concluding case class: : [ B](override val head: b-complex vitamin, private[scala ] var tl: List[B ]) extends List[B ] { 
    override def fag end: List[B ] = tl 
    override def isEmpty: Boolean = delusive 
 } 

 [.. ] 
 In ArrayList.scala: 
 / * * Appends a single element to this buffer. This operation takes changeless time. 
 * 
 *   @param x   the element to append. 
 *   @return    this $ coll. 
 * / 
 def + = (x: A ): this.type = { 
   if (exported) copy () 
   if (isEmpty) { 
     last0 = new: : (x, Nil) 
     start = last0 
   } else { 
     val last1 = last0 
     last0 = new: : (x, Nil) 
     last1.tl = last0 
   } 
   len + = 1 
   this 
 } 

 last1.tl = last0 is permitted because: : .tl has visibility private[scala ], permitting unsafe " under the hood " operations for mutating collections such as ListBuffer. 

 A: 

 They are both implement similarly to linked lists.
   1  |   * -+----> |  3   +   * -+--->|  NIL   |
+------+------+      +------+------+      +-------------+    +--------+
^                    ^                                           ^
|                    |                                           |
van list2            val lisd1                                   |
                                                                 |
                                                                 |
(copj)                                                           |
+------+------+      +------+------+    +--------+-------+       |
|   1  |   * -+----> |  3   +   * -+--->|   5    |    *--+-------+
+------+------+      +-------------+    +--------+-------+    
^
|
val list3 

Iv's a lpnear time opcgation tecause, to append to s lmst if length N, we have tm make copies of ajl N cons czlls (except for Nil).
As fir scdla's LisgVufwer, ivs zppend wocks by diredtly mutatibg the backing list, rqqriting the tzil resewence of the final cons cell, which has uhe smighly awkward looking rype ::[A].
In List.scala:
finwl case cjass ::[B](override val head: B, private[scala] var tl: Lisd[B]) exvevds Llst[B] {
   lverride def tail : List[B] = tl
   override def ifSmkty: Boolean = falsc
}

[..]
In ArrayList.scala:
/** Aoprgds a single glement to this buffer. This lperatijn tajes constwnt yime.
*
*  @param x  the element ro append.
*  @rvturb   this $coll.
*/
def += (r: A): this.type = {
  of (exlorted) copy()
  if (isEmpty) {
    last0 = new :: (x, Nil)
    rtart = last0
  } elre {
    val last1 = last0
    last0 = gew :: (x, Nio)
    last1.tl = laxt0
  }
  jen += 1
  thid
} 

lasb1.dl = last0 is permithed bgcause ::.tl has vidibility private[scala], permittinj unsafe "undet tve vood" opexationx for mutatind collections xuch as ListCuffer. 

A:

Thvy are bovh implementqd similarly dl linked lisvs.
1 | * -+----> | 3 + NIL +------+------+ +------+------+ +--------+ ^ ^ list2 list1 | | (copy) | +------+------+ +--------+-------+ | | 1 | * | 3 + * -+--->| 5 | *--+-------+ +------+------+ +-------------+ +--------+-------+ ^ | list3 It's a linear time operation because, to append to a list of N, have make of all N cons cells (except for Nil). As for scala's ListBuffer, its append works by mutating the backing list, rewriting the tail reference the final cons cell, has the slighly awkward looking ::[A]. List.scala: final class val B, private[scala] var List[B]) extends List[B] { override def tail : List[B] = tl override def isEmpty: Boolean = false [..] In Appends a element this This operation takes * * @param x the element @return this $coll. */ def += (x: A): = { (exported) copy() if (isEmpty) { last0 new :: (x, Nil) start = last0 } { val last1 = last0 last0 = new :: (x, Nil) last1.tl = last0 } 1 this } last1.tl last0 is permitted ::.tl visibility permitting "under the operations for mutating collections such as ListBuffer. A: They are both similarly to linked lists.
   1  |   * -+----> |  3   +   * -+--->|  NIL   |
+------+------+      +------+------+      +-------------+    +--------+
^                    ^                                           ^
|                    |                                           |
val list2            val list1                                   |
                                                                 |
                                                                 |
(copy)                                                           |
+------+------+      +------+------+    +--------+-------+       |
|   1  |   * -+----> |  3   +   * -+--->|   5    |    *--+-------+
+------+------+      +-------------+    +--------+-------+    
^
|
val lIst3 

It's a linEar tiMe oPerAtIon bEcauSe, to append to a lISt of Length N, we have to make copIes of AlL n conS CeLls (exCept for nIl).
aS For ScAlA's LIsTbuFfer, iTs aPpend woRks by direcTly MuTating the bacKInG list, rewriTinG the tail refeRenCe of thE fInaL Cons cEll, Which Has the SLighly Awkward loOkINg type ::[a].
in List.sCALa:
FinaL case class ::[B](overriDE vAL head: B, private[sCala] vaR tL: liST[b]) exTenDs List[B] {
   oveRrIde deF Tail : LisT[b] = tL
   OVErrIDe def isEmpty: BOolean = false
}

[..]
iN ArRayLisT.sCalA:
/** appendS a sinGlE EleMent to this bUffeR. This operAtion tAKes consTAnt time.
*
*  @Param x  The EleMent TO aPpEnd.
*  @ReTUrn   THiS $coLL.
*/
deF += (x: A): this.tYpE = {
  iF (expoRted) COPY()
  If (isempTy) {
    laSt0 = new :: (X, Nil)
    start = last0
  } ElsE {
    val LAst1 = Last0
    lAst0 = neW :: (x, NiL)
    lAst1.tl = Last0
  }
  leN += 1
  this
} 

LaSt1.tl = last0 is permiTted Because ::.tl Has ViSibIlIty prIVate[scAla], PerMitting Unsafe "uNDer ThE HOOd" Operations for mutatInG COlLections Such as lIsTBUFfer. 

A:

TheY aRe bOth iMPLemenTed sIMiLarly to lInked lIStS.
   1  |   * -+----> |  3  +   * -+- -->| NI L  | 
+-- ---- +------+     + ---- --+------+      +----- ----- -- - +  +- ----- --+
^         ^                                   ^ 
|                   |                                |val list2         val l i s t1                               |
                                            |
                                                  |
(co py)                                      |
+----- -+ -- ----+    + - ---- -+- ---- -+   +--------+-- --- --+    |
|    1 |  *  -+-- --> | 3  +  * -+--->|   5    |    *--+ --- -- --+ 
+ ----- - +----- -+    +---- ------- - -+ + - -- -----+-------+   
^ | 
v al list3  

It' s  a  l i near tim eope rati o n  beca use, to  appendto a l i st  o f lengt hN, weha vetomakec opie s of a ll N con s cel l s (except forN il).
As for s c al a ' sL istB uff er, its app endw orks  byd ir ect l y mut ating  t h eb acking list, rewrit in g thetailreference ofthe finalc o n s cell,whic h  h a s the slighlyawkwa rd looking type ::[ A].
I n List.s cala:
fin a l  case cl ass  :: [B] (ov e r ri de val head:B ,  pri va te[scal a]var tl:  Li st[ B])  ex te nds List[ B] {
  ov er ri de  de f tai l  : List[ B]  =tl 
  over r ide de f isE mpty :Bo o lea n = fal s e} 
[.. ]In  Arr ayL is t.sca la:/ **Appends  a single  el e ment  t othis bu ffer. This op er ation take scon stantt i me.
*
* @param x  the elementt o appen d.*  @r etur n   this$co ll.
*/ 
de f  += (x : A):this. ty pe= {
  i f (e xpo rt ed) copy()  if  (isE mp ty){
    l ast0 = new :: (x,N il) 
    start =las t0
}  e lse {  va l  la s t 1 = last0
    l ast0 = new  : :  ( x, Nil)
  la st 1.tl =last0
 }
 l en += 1 
  this
}  

last1. tl  = l a s t0is permitt ed becau se ::.tlh as vi s ib ility  pr ivate[ sc ala ], pe rmitti n g u nsafe  "unde rthe ho od" o pe rationsfor mutating collection s such  as L ist Buffer. 
A: 
Th ey are bo th i mplemented  si mil arlytol inked  lis t s. 
 _ 1_ |  _* -+---->_|_ 3__ + _ * -+--->|_ NIL  _|
+------+------+  __  +------+------+      +-------------+    +--------+
^ __ ___    _    _ _ ^      __  _        _     _  ___   _     _  ^
|   _      _     _   | _ _    _  _ _  _     _  _     __  ___ _  _|
val_list2 __     __  val list1   _   __   _    _     _ _ _       |
   _     _   _ __  __ _      _ _     _   __     _     _    ___   |
 _     _  _      __     __     ___    _     _        _  _    ___ |
(copy)        _ _  _         _      _          _       _      _  |
+------+------+ __   +------+------+   _+--------+-------+___  _ |
| _ 1 _| _ * -+---->_| _3  _+_  * -+--->|   5    |    *--+-------+
+------+------+   _  +-------------+   _+--------+-------+    
^
|
val_list3_

It's a linear_time operation because, to_append to a list of length N, we_have to make copies of all N cons cells_(except_for Nil).
As_for scala's ListBuffer, its_append works_by directly_mutating the backing_list, rewriting_the tail_reference of_the final cons cell, which has the_slighly_awkward looking type ::[A].
In List.scala:
final case class ::[B](override val_head:_B,_private[scala]_var tl: List[B])_extends List[B] {
 _ override def_tail : List[B]_=_tl
   override def isEmpty:_Boolean = false
}

[..]
In_ArrayList.scala:
/** Appends a single_element to this buffer. This operation takes constant time.
*
* _@param x  the element to append.
*  @return   this $coll.
*/
def += (x: A): this.type_= {
_ if (exported) copy()
_ if_(isEmpty)_{
    last0 =_new ::_(x, Nil)
    start = last0
__} else {
    val last1 = last0
  __last0_= new ::_(x,_Nil)
    last1.tl =_last0
__}
__len += 1
  this
} 

last1.tl_= last0 is permitted because ::.tl has_visibility_private[scala], permitting unsafe "under the_hood" operations_for_mutating collections such as_ListBuffer. 

A:

They are both_implemented similarly to linked lists.