Scala For The Impatient
Scala For The Impatient
!"#$%&'()*+*!,$*-.*/"%0)1,22*3455.*677*8&'()0*8909%:9;.
<(9*9:"7=)&"2*">*?,:,*,2;*!@@*(,0*07"A9;*;"A2*B"20&;9%,C7$D*,2;*#%"'%,119%0*A("*,%9
9,'9%*)"*=09*1"%9*1";9%2*7,2'=,'9*>9,)=%90*,%9*7""E&2'*9709A(9%9.*-B,7,*&0*,2*,))%,B)&:9
B("&B9F*&2*>,B)D*G*)(&2E*&)*&0*C$*>,%*)(9*1"0)*,))%,B)&:9*B("&B9*>"%*#%"'%,119%0*A("*A,2)*)"
1":9*C9$"2;*?,:,*"%*!@@.*-B,7,*(,0*,*B"2B&09*0$2),H*)(,)*&0*%9>%90(&2'*,>)9%*)(9*?,:,
C"&79%#7,)9.*G)*%=20*"2*)(9*?,:,*:&%)=,7*1,B(&29D*#%":&;&2'*,BB900*)"*,*(='9*09)*">*7&C%,%&90
,2;*)""70.*G)*91C%,B90*)(9*>=2B)&"2,7*#%"'%,11&2'*0)$79*A&)("=)*,C,2;"2&2'*"CI9B)J
"%&92),)&"2D*'&:&2'*$"=*,2*&2B%9192),7*79,%2&2'*#,)(*)"*,*29A*#,%,;&'1.*<(9*-B,7,
&2)9%#%9)9% 79)0*$"=*%=2*K=&BE*9H#9%&192)0D*A(&B(*1,E90*79,%2&2'*-B,7, :9%$*92I"$,C79.
62;D*7,0)*C=)*2")*79,0)D*-B,7,*&0*0),)&B,77$*)$#9;D*92,C7&2'*)(9*B"1#&79%*)"*>&2;*9%%"%0D*0"
)(,)*$"=*;"2L)*A,0)9*)&19*>&2;&2'*)(91*7,)9%*&2*%=22&2'*#%"'%,10*M"%*A"%09D*;"2L)*>&2;
)(91N.
-B,7,*&0*,*C&'*7,2'=,'9D*C=)*$"=*B,2*=09*&)*9>>9B)&:97$*A&)("=)*E2"A&2'*,77*">*&)0*;9),&70
&2)&1,)97$.*P,%)&2*Q;9%0E$D*)(9*B%9,)"%*">*-B,7,D*(,0*&;92)&>&9;*)(9*>"77"A&2'*79:970*">
9H#9%)&09*>"%*,##7&B,)&"2*#%"'%,119%0*,2;*7&C%,%$*;90&'29%0R
Y"%*9,B(*B(,#)9%*M,2;*"BB,0&"2,77$*>"%*&2;&:&;=,7*09B)&"20ND*G*&2;&B,)9*)(9*9H#9%&92B9
79:97. <(9*B(,#)9%0*#%"'%900*)(%"='(*79:970*65D*T5D*63D*T3D*6XD*TX.*W:92*&>*$"=*;"2L)
A,2)*)"*;90&'2*$"=%*"A2*7&C%,%&90D*E2"A&2'*,C"=)*)(9*)""70*)(,)*-B,7,*#%":&;90*>"%*7&C%,%$
;90&'29%0*B,2*1,E9*$"=*,*1"%9*9>>9B)&:9*7&C%,%$*=09%.
G*("#9*$"=*92I"$*79,%2&2'*-B,7,*A&)(*)(&0*C""E.*G>*$"=*>&2;*9%%"%0*"%*(,:9*0=''90)&"20*>"%
&1#%":9192)D*#79,09*:&0&) http://horstmann.com/scala ,2;*79,:9*,*B"1192).
5
Table of Contents
5. <(9*V,0&B0*M65N
3. !"2)%"7*-)%=B)=%90*,2;*Y=2B)&"20*M65N
X. 6%%,$0*M65N
Z. P,#0*,2;*<=#790*M65N
[. !7,0090*M65N
\. QCI9B)0*M65N
]. S,BE,'90*,2;*G1#"%)0*M65N
^. G2(9%&),2B9*M65N
_. Y&790*,2;*89'=7,%*WH#%900&"20*M65N
54. <%,&)0*MT5N
55. Q#9%,)"%0*MT5N
53. /&'(9%JQ%;9%*Y=2B)&"20*MT5N
5X. !"779B)&"20*M63N
5Z. S,))9%2*P,)B(&2'*,2;*!,09*!7,0090*M63N
5[. 622"),)&"20*M63N
5\. `PT*S%"B900&2'*M63N
5]. <$#9*S,%,19)9%0*MT3N
5^. 6;:,2B9;*<$#90 MT3N
5_. S,%0&2'*,2;*U"1,&2J-#9B&>&B*T,2'=,'90*M6XN
34. 6B)"%0*M6XN
35. G1#7&B&)0*MTXN
33. 6C0)%,B)*<$#90*MTXN
3X. /&'(9%Ja&2;9;*<$#90*MTXN
3Z. U97&1&)9;*B"2)&2=,)&"20*MTXN
3
1. The Basics (A1)
G2*)(&0*B(,#)9%D*$"=*A&77*79,%2*("A*)"*=09*-B,7,*,0*,2*&2;=0)%&,7J0)%92')(*#"BE9)*B,7B=7,)"%D
A"%E&2'*&2)9%,B)&:97$*A&)(*2=1C9%0*,2;*,%&)(19)&B*"#9%,)&"20.*b9*&2)%";=B9*,*2=1C9%*">
&1#"%),2)*-B,7,*B"2B9#)0*,2;*&;&"10*,7"2'*)(9*A,$.*c"=*A&77*,70"*79,%2*("A*)"*C%"A09
)(9*-B,7,;"B*;"B=192),)&"2*,)*,*C9'&229%L0*79:97.
/&'(7&'()0*">*)(&0*&2)%";=B)&"2*,%9R
d e0&2'*)(9*-B,7,*&2)9#%9)9%
d U9>&2&2'*:,%&,C790*A&)( var ,2; val
d f=19%&B*)$#90
d e0&2'*"#9%,)"%0*,2;*>=2B)&"20
d f,:&',)&2'*-B,7,;"B
d G20),77*-B,7,
d P,E9*0=%9*)(,)*)(9 scala/bin ;&%9B)"%$*&0*"2*)(9*S6</
d Q#92*,*B"11,2;*0(977*&2*$"=%*"#9%,)&2'*0$0)91
d <$#9 scala >"77"A9;*C$*)(9 Wf<W8 E9$.
Tip: U"2L)*7&E9*)(9*B"11,2;*0(977g*<(9%9*,%9*")(9%*A,$0*">*%=22&2'*)(9
&2)9%#%9)9%h099 ())#Rii("%0)1,22.B"1i0B,7,i&20),77.
f"A*)$#9*B"11,2;0*>"77"A9;*C$ Wf<W8.*W,B(*)&19D*)(9*&2)9%#%9)9%*;&0#7,$0*)(9*,20A9%.
Y"%*9H,1#79D*&>*$"=*)$#9 8 * 5 + 2 M,0*0("A2*&2*C"7;>,B9*C97"AND*$"=*'9)*,2*,20A9%*Z3.
scala> 8 * 5 + 2
res0: Int = 42
60*$"=*B,2*099D*)(9*&2)9%#%9)9%*,70"*;&0#7,$0*)(9*)$#9*">*)(9*%90=7)h&2*"=%*9H,1#790D IntD
DoubleD*,2; java.lang.String.
X
c"=*B,2*B,77*19)(";0.*U9#92;&2'*"2*("A*$"=*7,=2B(9;*)(9*&2)9%#%9)9%D*$"=*1,$*C9*,C79
)"*=09 tab completion.*<%$*)$#&2' res2.to ,2;*)(92*(&)*)(9 <6V E9$.*U&;*)(9*&2)9%#%9)9%
">>9%*B("&B90*0=B(*,0
res2.toUpperCase
670"*)%$*(&))&2'*)(9*j*,2;*k*,%%"A*E9$0.*G2*1"0)*&1#79192),)&"20D*$"=*A&77*099*)(9
#%9:&"=07$*&00=9;*B"11,2;0D*,2;*$"=*B,2*9;&)*)(91.*<%$*)(9*lD*mD*,2; UWT E9$0*)"
B(,2'9*)(9*7,0)*B"11,2;*)"
res2.toLow
LowerCase
60*$"=*B,2*099D*)(9*-B,7,*&2)9%#%9)9%*%9,;0*,2*9H#%900&"2D*9:,7=,)90*&)D*#%&2)0*&)D*,2;*%9,;0
)(9*29H)*9H#%900&"2.*<(&0*&0*B,779;*)(9 read-eval-print loop "%*8WST.
Tip: <(9*8WST*&0*$"=%*>%&92;.*V9B,=09*$"=*'9)*&20),2)*>99;C,BED*$"=*A&77*>997
92B"=%,'9;*)"*9H#9%&192)D*,2;*$"=*A&77*>997*'"";*A(929:9%*0"19)(&2'*A"%E0.
G)*&0*,*'"";*&;9,*)"*E99#*,2*9;&)"%*A&2;"A*"#92*,)*)(9*0,19*)&19*0"*$"=*B,2
B"#$*,2;*#,0)9*0=BB900>=7*B";9*02&##9)0*>"%*7,)9%*=09.*670"D*,0*$"=*)%$*1"%9
B"1#79H*9H,1#790D*$"=*1,$*A,2)*)"*B"1#"09*)(91*&2*)(9*9;&)"%*,2;*)(92
#,0)9*)(91*&2)"*)(9*8WST.
Z
c"=*B,2*=09*$"=%*:,%&,C790*&2*0=C09K=92)*9H#%900&"20R
f")9*)(,)*$"=*299;*2")*0#9B&>$*)(9*)$#9*">*,*:,%&,C79.*G)*&0*&2>9%%9;*>%"1*)(9*)$#9*">*)(9
:,7=9*A&)(*A(&B(*$"=*&2&)&,7&p9*&).*MG)*&0*,2*9%%"%*)"*;9B7,%9*,*:,%&,C79*A&)("=)*,2*&2&)&,7
:,7=9.N
/"A9:9%D*$"=*B,2*0#9B&>$*)(9*)$#9*&>*29B900,%$.*Y"%*9H,1#79D
b(929:9%*G*1":9*C,BE*,2;*>"%)(*C9)A992*?,:,*,2;*-B,7,D*G*>&2;*)(,)*1$
>&2'9%0*A%&)9*;9B7,%,)&"20*0=B(*,0 String greeting "2*,=)"#&7")D*,2;*G*(,:9*)"
%9A%&)9*)(91*,0 greeting: String.*<(&0*&0*,*C&)*,22"$&2'D*C=)*A(92*G*A"%E
A&)(*B"1#79H*-B,7,*#%"'%,10D*G*%9,77$*,##%9B&,)9*)(,)*G*;"2L)*(,:9*)"*;9B%$#)
)$#9*!J0)$79*;9B7,%,)&"20.
scala> answer = 0
<console>:6: error: reassignment to val
<"*;9B7,%9*,*:,%&,C79*A("09*B"2)92)0*B,2*:,%$D*=09*, varR
var counter = 0
counter = 1 // QED*B,2*B(,2'9*, var
Note: c"=*1,$*(,:9*2")&B9;*)(,)*)(9%9*A9%9*2"*091&B"7"20*,>)9%*:,%&,C79
;9B7,%,)&"20*"%*,00&'2192)0.*G2*-B,7,D*091&B"7"20*,%9*"27$*%9K=&%9;*&>*$"=
(,:9*1=7)O*0),)9192)0*"2*)(9*0,19*7&29.
[
c"=*B,2*;9B7,%9*1=7)O*:,%&,C790*)"'9)(9%R
var i, j = 0
var greeting, message: String = null
"%D*1"%9*9HB&)&2'7$D
G2*-B,7,D*)(9%9*&0*2"*299;*>"%*A%,##9%*)$#90.*G)*&0*)(9*I"C*">*)(9*-B,7,*B"1#&79%*)"*B"2:9%)
C9)A992*#%&1&)&:9*)$#90*,2;*A%,##9%0.*Y"%*9H,1#79D*&>*$"=*1,E9*,2*,%%,$*"> IntD*$"=*'9)
,2 int[] ,%%,$*&2*)(9*:&%)=,7*1,B(&29.
\
0"*"2.*<(9 to 19)(";*)(,)*$"=*(,:9*0992*,C":9*&0*,B)=,77$*,*19)(";*">*)(9 RichInt B7,00.
G2*)(9*9H#%900&"2
1.to(10)
Note: G2*-B,7,D*$"=*=09*19)(";0D*2")*B,0)0D*)"*B"2:9%)*C9)A992*2=19%&B*)$#90.
Y"%*9H,1#79D 99.44.toInt &0 99D*,2; 99.toChar &0 'c'.*Q>*B"=%09D*,0*&2*?,:,D
)(9 toString 19)(";*B"2:9%)0*,2$*"CI9B)*)"*,*0)%&2'.
val answer = 8 * 5 + 2
a + b
&0*,*0("%)(,2;*>"%
a.+(b)
/9%9D + &0*)(9*2,19*">*)(9*19)(";.*-B,7,*(,0*2"*0&77$*#%9I=;&B9*)(,)*,*19)(";*2,19*B,2
"27$*B"2),&2*,7#(,2=19%&B*B(,%,B)9%0.*c"=*B,2*;9>&29*19)(";0*A&)(*I=0)*,C"=)*,2$
0$1C"70.*Y"%*9H,1#79D*)(9 BigInt B7,00*;9>&290*,*19)(";*B,779; /%.*G)*%9)=%20*,*#,&%
B"2),&2&2'*)(9*K=")&92)*,2;*%91,&2;9%*">*,*;&:&0&"2.
G2*'929%,7D*$"=*B,2*A%&)9
]
a method b
,0*,*0("%)(,2;*>"%
a.method(b)
1.to(10)
$"=*B,2*A%&)9
1 to 10
e09*A(,)9:9%*$"=*)(&2E*&0*9,0&9%*)"*%9,;.*V9'&22&2'*-B,7,*#%"'%,119%0*)92;*)"*0)&BE*)"
)(9*?,:,*0$2),HD*,2;*)(,)*&0*I=0)*>&29.*Q>*B"=%09D*9:92*)(9*1"0)*(,%;929;*?,:,
#%"'%,119%0*0991*)"*#%9>9% a + b ":9% a.+(b).
<(9%9*&0*"29*2"),C79*;&>>9%92B9*C9)A992*-B,7,*,2;*?,:,*"%*!@@.*-B,7,*;"90*2")*(,:9 ++ "%
-- "#9%,)"%0.*G20)9,;D*0&1#7$*=09 +=1 "% -=1.
-"19*#9"#79*A"2;9%*A(9)(9%*)(9%9*&0*,2$*;99#*%9,0"2*>"%*-B,7,L0*%9>=0,7*)"*#%":&;9*,
++ "#9%,)"%.*Mf")9*)(,)*$"=*B,2L)*0&1#7$*&1#79192)*,*19)(";*B,779; ++.*-&2B9*)(9 Int
B7,00*&0*&11=),C79D*0=B(*,*19)(";*B"=7;2L)*B(,2'9*,2*&2)9'9%*:,7=9.N*<(9*-B,7,*;90&'29%0
;9B&;9;*&)*A,02L)*A"%)(*(,:&2'*$9)*,2")(9%*0#9B&,7*%=79*I=0)*)"*0,:9*"29*E9$0)%"E9.
<(,)L0*1=B(*C9))9%*)(,2*?,:,D*A(9%9*$"=*A"=7;*(,:9*(,;*)"*B,77
x.multiply(x).multiply(x).
Note: G2*?,:,D*$"=*B,22")*":9%7",;*"#9%,)"%0D*,2;*)(9*?,:,*;90&'29%0*B7,&19;
)(&0*&0*,*'"";*)(&2'*C9B,=09*&)*#%9:92)0*$"=*>%"1*&2:92)&2'*B%,p$*"#9%,)"%0*7&E9
!@$&* )(,)*1,E9*$"=%*#%"'%,1*&1#"00&C79*)"*%9,;.*Q>*B"=%09D*)(,)L0*0&77$.*G2
?,:,D*$"=*B,2*1,E9*$"=%*#%"'%,10*I=0)*,0*(,%;*)"*%9,;*C$*=0&2'*B%,p$*19)(";
2,190*7&E9 qxywz.*-B,7,*,77"A0*$"=*)"*;9>&29*"#9%,)"%0D*79,:&2'*&)*)"*$"=*)"*=09
)(&0*>9,)=%9*A&)(*%90)%,&2)*,2;*'"";*),0)9.
^
1.5. Calling Functions and Methods
-B,7,*(,0*>=2B)&"20*&2*,;;&)&"2*)"*19)(";0.*G)*0&1#79%*)"*=09*1,)(91,)&B,7*>=2B)&"20*0=B(
,0 min "% pow &2*-B,7,*)(,2*&2*?,:,h$"=*299;*2")*=09*0),)&B*19)(";0*&2*,*B7,00.
sqrt(2) // $&97;0*5.Z5Z35X[\3X]X4_[5
pow(2, 4) // $&97;0*5\.4
min(3, Pi) // $&97;0*X.4
c"=*B,2*&1#"%)*)(91*A&)(*)(9*0),)9192)
BigInt.probablePrime(100, util.Random)
&2*)(9*8WST.*c"=L77*'9)*,*2=1C9%*0=B(*,0*54X_ZZ]_^4Z_53443][Z^\[Z43Z4]5X.*f")9
)(,)*)(9*B,77 BigInt.probablePrime &0*I=0)*7&E9*,*0),)&B*19)(";*B,77*&2*?,:,.
_
-B,7,*19)(";0*A&)("=)*#,%,19)9%0*">)92 ;"2L)*=09*#,%92)(9090.*Y"%*9H,1#79D*)(9*6SG*">
)(9 StringOps B7,00*0("A0*,*19)("; distinctD*A&)("=) ()D*)"*'9)*)(9*;&0)&2B)*79))9%0*&2*,
0)%&2'.*c"=*B,77*&)*,0
"Hello".distinct
<(9*%=79*">*)(=1C*&0*)(,)*,*#,%,19)9%7900*19)(";*)(,)*;"902L)*1";&>$*)(9*"CI9B)*(,0*2"
#,%92)(9090.*b9*;&0B=00*)(&0*>=%)(9%*&2 )(9*n!7,0090o*B(,#)9%.
c"=*B,2*)(&2E*">*)(&0*,0*,2*":9%7",;9;*>"%1*">*)(9 () "#9%,)"%.*G)*&0*&1#79192)9;*,0*,
19)(";*A&)(*)(9*2,19 apply.*Y"%*9H,1#79D*&2*)(9*;"B=192),)&"2*">*)(9 StringOps B7,00D
$"=*A&77*>&2;*,*19)(";
"Hello".apply(4)
BigInt("1234567890")
&0*,*0("%)B=)*>"%
BigInt.apply("1234567890")
BigInt("1234567890") * BigInt("112358111321")
54
1.7. Scaladoc
?,:,*#%"'%,119%0*=09*?,:,;"B*)"*2,:&',)9*)(9*?,:,*6SG.*-B,7,*(,0*&)0*"A2*:,%&,2)D*B,779;
-B,7,;"B*M099 Y&'=%9*5N.
Y&'=%9*5J5R <(9*W2)%$*S,'9*>"%*-B,7,;"B
f,:&',)&2'*-B,7,;"B*&0*,*C&)*1"%9*B(,7792'&2'*)(,2*?,:,;"B.*-B,7,*B7,0090*)92;*)"*(,:9
1,2$*1"%9*B"2:92&92B9*19)(";0*)(,2*?,:,*B7,0090.*-"19*19)(";0*=09*>9,)=%90*)(,)
$"= (,:92L)*79,%29;*$9).*Y&2,77$D*0"19 >9,)=%90*,%9*9H#"09;*,0*)(9$*,%9*&1#79192)9;D*2")
,0*)(9$*,%9*=09;.*M<(9*-B,7,*)9,1*&0*A"%E&2'*"2*&1#%":&2'*)(9*-B,7,;"B*#%9092),)&"2D*0"
)(,)*&)*A&77*C9*1"%9*,##%",B(,C79*)"*C9'&229%0*&2*)(9*>=)=%9.N
/9%9*,%9*0"19*)�*>"%*2,:&',)&2'*-B,7,;"B*,0*,*29AB"19%*)"*)(9*7,2'=,'9.
c"=*B,2*C%"A09*-B,7,;"B*"27&29*,) ())#RiiAAA.0B,7,J7,2'."%'i,#&D*C=)*&)*&0*,*'"";*&;9,*)"
;"A27",;*,*B"#$*>%"1 ())#RiiAAA.0B,7,J7,2'."%'i;"A27",;0O,#& ,2;*&20),77*&)*7"B,77$.
e27&E9*?,:,;"BD*A(&B(*#%9092)0*,2*,7#(,C9)&B,7*7&0)&2'*">*B7,0090D*-B,7,;"BL0*B7,00*7&0)*&0
0"%)9;*C$*#,BE,'90.*G>*$"=*E2"A*)(9*B7,00*2,19*C=)*2")*)(9*#,BE,'9*2,19D*=09*)(9*>&7)9%
"2*)(9*)"#*79>)*B"%29%*M099 Y&'=%9*3N.
55
Y&'=%9*5J3R <(9*Y&7)9%*V"H*&2*-B,7,;"B
!7&BE*"2*)(9*`*0$1C"7*)"*B79,%*)(9*>&7)9%.
f")9*)(9*Q*,2;*!*0$1C"70*29H)*)"*9,B(*B7,00*2,19.*<(9$*79)*$"=*2,:&',)9*)"*)(9*B7,00*M!N
"%*)(9*B"1#,2&"2*"CI9B)*MQN.
-B,7,;"B*B,2*C9*,*C&)*":9%A(971&2'.*a99#*)(909*)�*&2*1&2;R
c"=*0=##7$*,*>=2B)&"2D*">)92*&2*,*:9%$*B"1#,B)*2"),)&"2D*A(92*$"=*B,77*)(9
19)(";.*60*,2*9H,1#79D*)(9*B,77 s.count(_.isUpper) B"=2)0*)(9*2=1C9%*">
=##9%B,09*B(,%,B)9%0.*b9*A&77*;&0B=00*)(&0*0)$79*">*#%"'%,11&2'*&2*1=B(*1"%9
;9),&7*&2 )(9*n/&'(9%*Q%;9%*Y=2B)&"20o*B(,#)9%.
53
d c"=L77*"BB,0&"2,77$*%=2*&2)"*B7,0090*0=B(*,0 Range "% Seq[Char].*<(9$*19,2*A(,)
$"=%*&2)=&)&"2*)9770*$"=h,*%,2'9*">*2=1C9%0D*,*09K=92B9*">*B(,%,B)9%0.*c"=*A&77
79,%2*,77*,C"=)*)(909*B7,0090*,0*$"=*;97:9*1"%9*;99#7$*&2)"*-B,7,.
d U"2L)*'9)*;&0B"=%,'9;*)(,)*)(9%9*,%9*0"*1,2$*19)(";0.*G)L0*)(9*-B,7,*A,$*)"
#%":&;9*7")0*">*19)(";0*>"%*9:9%$*B"2B9&:,C79*=09*B,09.*b(92*$"=*299;*)"*0"7:9
,*#,%)&B=7,%*#%"C791D*I=0)*7""E*>"%*,*19)(";*)(,)*&0*=09>=7.*P"%9*">)92*)(,2*2")D
)(9%9*&0*"29*)(,)*0"7:90*$"=%*),0ED*A(&B(*19,20*$"=*;"2L)*(,:9*)"*A%&)9*0"*1=B(
B";9*$"=%097>.
d Y&2,77$D*;"2L)*A"%%$*&>*$"=*%=2*&2)"*)(9*"BB,0&"2,7*&2;9B&#(9%,C79*&2B,2),)&"2D
0=B(*,0*)(&0*"29*&2*)(9 StringOps B7,00R
def patch [B >: Char, That](from: Int, patch: GenSeq[B], replaced: Int)(implicit bf: Ca
1.8. Exercises
5. G2*)(9*-B,7,*8WSTD*)$#9 3. >"77"A9;*C$*)(9 <6V E9$.*b(,)*19)(";0*B,2*C9
,##7&9;g
3. G2*)(9*-B,7,*8WSTD*B"1#=)9*)(9*0K=,%9*%"")*">*XD*,2;*)(92*0K=,%9*)(,)*:,7=9.*V$
("A*1=B(*;"90*)(9*%90=7)*;&>>9%*>%"1*Xg*M/&2)R*<(9 res :,%&,C790*,%9*$"=%
>%&92;.N
X. 6%9*)(9 res :,%&,C790 val "% varg
Z. -B,7,*79)0*$"=*1=7)$*,*0)%&2'*A&)(*,*2=1C9%h)%$*"=) "crazy" * 3 &2*)(9
8WST.*b(,)*;"90*)(&0*"#9%,)&"2*;"g*b(9%9*B,2*$"=*>&2;*&)*&2*-B,7,;"Bg
[. b(,)*;"90 10 pow 2 19,2g*G2*A(&B(*B7,00*&0*)(9 pow 19)(";*;9>&29;g
\. e0&2' BigIntD*B"1#=)9*3543Z.
]. b(,)*;"*$"=*299;*)"*&1#"%)*0"*)(,)*$"=*B,2*'9)*,*%,2;"1*#%&19*,0
probablePrime(100, Random)D*A&)("=)*,2$*K=,7&>&9%0*C9>"%9 probablePrime ,2;
Randomg
^. Q29*A,$*)"*B%9,)9*%,2;"1*>&79*"%*;&%9B)"%$*2,190*&0*)"*#%";=B9*,*%,2;"1 BigInt
,2;*B"2:9%)*&)*)"*C,09*X\D*$&97;&2'*,*0)%&2'*0=B(*,0 "qsnvbevtomcj38o06kul".*S"E9
,%"=2;*-B,7,;"B*)"*>&2;*,*A,$*">*;"&2'*)(&0*&2*-B,7,.
_. /"A*;"*$"=*'9)*)(9*>&%0)*B(,%,B)9%*">*,*0)%&2'*&2*-B,7,g*<(9*7,0)*B(,%,B)9%g
54. b(,)*;"*)(9 takeD dropD takeRightD*,2; dropRight 0)%&2'*>=2B)&"20*;"g*b(,)
,;:,2),'9i;&0,;:,2),'9*;"*)(9$*(,:9*":9%*=0&2' substringg
5X
2. Control Structures and Functions (A1)
G2*)(&0*B(,#)9%D*$"=*A&77*79,%2*("A*)"*&1#79192)*B"2;&)&"20D*7""#0D*,2;*>=2B)&"20*&2*-B,7,.
c"=*A&77*92B"=2)9%*,*>=2;,192),7*;&>>9%92B9*C9)A992*-B,7,*,2;*")(9%*#%"'%,11&2'
7,2'=,'90.*G2*?,:,*"%*!@@D*A9*;&>>9%92)&,)9*C9)A992 expressions M0=B(*,0 3 + 4N*,2;
statements M>"%*9H,1#79D*,2 if 0),)9192)N.*62*9H#%900&"2*(,0*,*:,7=9F*,*0),)9192)*B,%%&90
"=)*,2*,B)&"2.*G2*-B,7,D*,71"0)*,77*B"20)%=B)0*(,:9*:,7=90.*<(&0*>9,)=%9*B,2*1,E9*#%"'%,10
1"%9*B"2B&09*,2;*9,0&9%*)"*%9,;.
/9%9*,%9*)(9*(&'(7&'()0*">*)(&0*B(,#)9%R
d 62 if 9H#%900&"2*(,0*,*:,7=9
d 6*C7"BE*(,0*,*:,7=9h)(9*:,7=9*">*&)0*7,0)*9H#%900&"2
d <(9*-B,7, for 7""#*&0*7&E9*,2*n92(,2B9;o*?,:, for 7""#
d -91&B"7"20*,%9*M1"0)7$N*"#)&"2,7
d <(9 void )$#9*&0 Unit
d 6:"&;*=0&2' return &2*,*>=2B)&"2
d V9A,%9*">*1&00&2' = &2*,*>=2B)&"2*;9>&2&)&"2
d WHB9#)&"20*A"%E*I=0)*7&E9*&2*?,:,*"%*!@@D*C=)*$"=*=09*,*n#,))9%2*1,)B(&2'o
0$2),H*>"% catch.
d -B,7,*(,0*2"*B(9BE9;*9HB9#)&"20
if (x > 0) 1 else -1
(,0*,*:,7=9*">*5*"%*J5D*;9#92;&2'*"2*)(9*:,7=9*"> x.*c"=*B,2*#=)*)(,)*:,7=9*&2*,*:,%&,C79R
<(&0*(,0*)(9*0,19*9>>9B)*,0
if (x > 0) s = 1 else s = -1
/"A9:9%D*)(9*>&%0)*>"%1*&0*C9))9%R*G)*B,2*C9*=09;*)"*&2&)&,7&p9*, val.*G2*)(9*09B"2;*>"%1D s
299;0*)"*C9*, var.
M60*,7%9,;$*192)&"29;D*091&B"7"20*,%9*1"0)7$*"#)&"2,7*&2*-B,7,h099 -9B)&"2*3N.
5Z
?,:,*,2;*!@@*(,:9*, ?: "#9%,)"%*>"%*)(&0*#=%#"09.*<(9*9H#%900&"2
x > 0 ? 1 : -1 // ?,:,*"%*!@@
&0*)(9*B"11"2*0=#9%)$#9*">*C")(*C%,2B(90.*G2*)(&0*9H,1#79D*"29*C%,2B(*&0*,
java.lang.StringD*,2;*)(9*")(9%*,2 Int.*<(9*B"11"2*0=#9%)$#9*&0*B,779; Any.*M-99 )(9
n<(9*-B,7,*<$#9*/&9%,%B($o*B(,#)9% >"%*;9),&70.N
if (x > 0) 1
)(92*&)*&0*#"00&C79*)(,)*)(9 if 0),)9192)*$&97;0*2"*:,7=9.*/"A9:9%D*&2*-B,7,D*9:9%$
9H#%900&"2*&0*0=##"09;*)"*(,:9 some :,7=9.*<(&0*&0*>&29009;*C$*&2)%";=B&2'*,*B7,00 Unit
)(,)*(,0*"29*:,7=9D*A%&))92*,0 ().*<(9 if 0),)9192)*A&)("=)*,2 else &0*9K=&:,792)*)"
if (x > 0) 1 else ()
Caution: <(9*8WST*&0*1"%9*29,%0&'()9;*)(,2*)(9*B"1#&79%h&)*"27$*0990*"29
7&29*">*B";9*,)*,*)&19.*Y"%*9H,1#79D*A(92*$"=*)$#9
5[
if (x > 0) 1
else if (x == 0) 0 else -1
G>*$"=*A,2)*)"*C%9,E*)(9*7&29*C9>"%9*)(9*9709D*=09*C%,B90R
if (x > 0) { 1
} else if (x == 0) 0 else -1
<(&0*&0*"27$*,*B"2B9%2*&2*)(9*8WST.*G2*,*B"1#&79;*#%"'%,1D*)(9*#,%09%*A&77
>&2;*)(9 else "2*)(9*29H)*7&29.
Tip: G>*$"=*A,2)*)"*#,0)9*,*C7"BE*">*B";9*&2)"*)(9*8WST*A&)("=)*A"%%$&2'
,C"=)*&)0*29,%0&'()9;2900D*=09 paste mode.*<$#9
:paste
<(92*#,0)9*&2*)(9*B";9*C7"BE*,2;*)$#9 !Qf<8QT@a.*<(92*)(9*8WST*,2,7$p90
)(9*C7"BE*&2*&)0*92)&%9)$.
/"A9:9%D*&>*$"=*A,2)*)"*(,:9*1"%9*)(,2*"29*0),)9192)*"2*,*0&2'79*7&29D*$"=*299;*)"
09#,%,)9*)(91*A&)(*091&B"7"20.*Y"%*9H,1#79D
if (n > 0) { r = r * n; n -= 1 }
G>*$"=*A,2)*)"*B"2)&2=9*,*7"2'*0),)9192)*":9%*)A"*7&290D*$"=*299;*)"*1,E9*0=%9*)(,)*)(9
>&%0)*7&29*92;0*&2*,*0$1C"7*)(,) cannot be )(9*92;*">*,*0),)9192).*62*"#9%,)"%*&0*">)92*,
'"";*B("&B9R
5\
s = s0 + (v - v0) * t + // <(9 + )9770*)(9*#,%09%*)(,)*)(&0*&0 not )(9*92;
0.5 * (a - a0) * t * t
G2*#%,B)&B9D*7"2'*9H#%900&"20*=0=,77$*&2:"7:9*>=2B)&"2*"%*19)(";*B,770D*,2;*)(92*"29
;"902L)*299;*)"*A"%%$*1=B(h,>)9%*,2*"#92&2' (D*)(9*B"1#&79%*A"2L)*&2>9%*)(9*92;*">*,
0),)9192)*=2)&7*&)*(,0*0992*)(9*1,)B(&2' ).
G2*)(9*0,19*0#&%&)D*-B,7,*#%"'%,119%0*>,:"%*)(9*a9%2&'(,2*q*8&)B(&9*C%,B9*0)$79R
if (n > 0) {
r = r * n
n -= 1
}
<(9*7&29*92;&2'*A&)(*, { 092;0*,*B79,%*0&'2,7*)(,)*)(9%9*&0*1"%9*)"*B"19.
P,2$*#%"'%,119%0*B"1&2'*>%"1*?,:,*"%*!@@*,%9*&2&)&,77$*=2B"1>"%),C79*,C"=)*"1&))&2'
091&B"7"20.*G>*$"=*#%9>9%*)(91D*I=0)*#=)*)(91*&2h)(9$*;"*2"*(,%1.
<(9*:,7=9*">*)(9 { } C7"BE*&0*)(9*7,0)*9H#%900&"2D*0("A2*(9%9*&2*C"7;.*<(9*:,%&,C790 dx
,2; dyD*A(&B(*A9%9*"27$*299;9;*,0*&2)9%19;&,)9*:,790*&2*)(9*B"1#=),)&"2D*,%9*29,)7$
(&;;92*>%"1*)(9*%90)*">*)(9*#%"'%,1.
G2*-B,7,D*,00&'2192)0*(,:9*2"*:,7=9D*"%D*0)%&B)7$*0#9,E&2'D*)(9$*(,:9*,*:,7=9*">*)$#9 Unit.
<(9 Unit )$#9*&0*)(9*9K=&:,792)*">*)(9 void )$#9*&2*?,:,*,2;*!@@.*b(9%9,0 void (,0*2"
:,7=90D*)(9 Unit )$#9*(,0*,*0&2'79*:,7=9*A%&))92*,0 ().*MG>*$"=*,%9*0"*&2B7&29;D*$"=*B,2
#"2;9%*)(9*;&>>9%92B9*C9)A992*,2*91#)$*A,779)*,2;*,*A,779)*A&)(*"29*;"77,%*)(,)*$"=
,%92L)*,77"A9;*)"*0#92;.N
6*C7"BE*)(,)*92;0*&2*,2*,00&'2192)*0),)9192)D*0=B(*,0
5]
{ r = r * n; n -= 1 }
x = y = 1 // f"
2.4. Loops
-B,7,*(,0*)(9*0,19 while ,2; do 7""#0*,0*?,:,*,2;*!@@.*Y"%*9H,1#79D
while (n > 0) {
r = r * n
n -= 1
}
for (i <- 1 to n)
r = r * i
<(9*B"20)%=B)
5^
Note: <(9%9*&0*2" val "% var C9>"%9*)(9*:,%&,C79*&2*)(9 for 7""#.*<(9*)$#9*">
)(9*:,%&,C79*&0*)(9*979192)*)$#9*">*)(9*B"779B)&"2.*<(9*0B"#9*">*)(9*7""#
:,%&,C79*9H)92;0*=2)&7*)(9*92;*">*)(9*7""#.
b(92*)%,:9%0&2'*,*0)%&2'*"%*,%%,$D*$"=*">)92*299;*,*%,2'9*>%"1*4*)" n J*5.*G2*)(,)*B,09D*=09
)(9 until 19)(";*&20)9,;*">*)(9 to 19)(";.*G)*%9)=%20*,*%,2'9*)(,)*;"902L)*&2B7=;9*)(9
=##9%*C"=2;.
val s = "Hello"
var sum = 0
for (i <- 0 until s.size
s.size) // T,0)*:,7=9*>"% i &0 s.size - 1
sum += s(i)
G2*)(&0*9H,1#79D*)(9%9*&0*,B)=,77$*2"*299;*)"*=09*&2;9H90.*c"=*B,2*;&%9B)7$*7""#*":9%*)(9
B(,%,B)9%0R
var sum = 0
for (ch <- "Hello") sum += ch
G2*-B,7,D*7""#0*,%9*2")*=09;*,0*">)92*,0*&2*")(9%*7,2'=,'90.*60*$"=*A&77*099*&2 )(9*n/&'(9%
Q%;9%*Y=2B)&"20o*B(,#)9%D*$"=*B,2*">)92*#%"B900*)(9*:,7=90*&2*,*09K=92B9*C$*,##7$&2'*,
>=2B)&"2*)"*,77*">*)(91D*A(&B(*B,2*C9*;"29*A&)(*,*0&2'79*19)(";*B,77.
5. e09*,*V""79,2*B"2)%"7*:,%&,C79*&20)9,;
3. e09*290)9;*>=2B)&"20h$"=*B,2 return >%"1*)(9*1&;;79*">*,*>=2B)&"2
X. e09*)(9 break 19)(";*&2*)(9 Breaks "CI9B)R
import util.control.Breaks._
breakable {
for (...) {
if (...) break; // WH&)0*)(9 breakable C7"BE
...
}
}
<(9*B"2)%"7*)%,20>9%*&0*;"29*C$*)(%"A&2'*,2;*B,)B(&2'*,2*9HB9#)&"2D*0"
$"=*A,2)*)"*,:"&;*)(&0*19B(,2&01*A(92*)&19*&0*">*)(9*90092B9.
5_
2.5. Advanced For Loops and For Comprehensions
G2*)(9*#%9B9;&2'*09B)&"2D*$"=*0,A*)(9*C,0&B*>"%1*">*)(9 for 7""#.*/"A9:9%D*)(&0*B"20)%=B)
&0*1=B(*%&B(9%*&2*-B,7,*)(,2*&2*?,:,*"%*!@@.*<(&0*09B)&"2*B":9%0*)(9*,;:,2B9;*>9,)=%90.
f")9*)(,)*)(9%9*&0*2"*091&B"7"2*C9>"%9*)(9 if.
c"=*B,2*(,:9*,2$*2=1C9%*"> definitionsD*&2)%";=B&2'*:,%&,C790*)(,)*B,2*C9*=09;*&20&;9*)(9
7""#R
<(9*'929%,)9;*B"779B)&"2*&0*B"1#,)&C79*A&)(*)(9*>&%0)*'929%,)"%.
Note: G>*$"=*#%9>9%D*$"=*B,2*92B7"09*)(9*'929%,)"%0D*'=,%;0D*,2;*;9>&2&)&"20*">
, for 7""#*&20&;9*C%,B90D*,2;*$"=*B,2*=09*29A7&290*&20)9,;*">*091&B"7"20*)"
09#,%,)9*)(91R
34
for { i <- 1 to 3
from = 4 - i
j <- from to 3 }
2.6. Functions
-B,7,*(,0*>=2B)&"20*&2*,;;&)&"2*)"*19)(";0.*6*19)(";*"#9%,)90*"2*,2*"CI9B)D*C=)*,
>=2B)&"2*;"902L). !@@*(,0*>=2B)&"20*,0*A977D*C=)*&2*?,:,D*$"=*&1&),)9*)(91*A&)(*0),)&B
19)(";0.
<"*;9>&29*,*>=2B)&"2D*$"=*0#9B&>$*)(9*>=2B)&"2L0*2,19D*#,%,19)9%0D*,2;*C";$D*7&E9*)(&0R
c"=*1=0)*0#9B&>$*)(9*)$#90*">*,77*#,%,19)9%0D*C=)D*,0*7"2'*,0*)(9*>=2B)&"2*&0*2")*%9B=%0&:9D
$"=*299;*2")*0#9B&>$*)(9*%9)=%2*)$#9.*<(9*-B,7,*B"1#&79%*;9)9%1&290*)(9*%9)=%2*)$#9*>%"1
)(9*)$#9*">*)(9*9H#%900&"2*)"*)(9*%&'()*">*)(9 = 0$1C"7.
G>*)(9*C";$*">*)(9*>=2B)&"2*%9K=&%90*1"%9*)(,2*"29*9H#%900&"2D*=09*,*C7"BE.*<(9*7,0)
9H#%900&"2*">*)(9*C7"BE*C9B"190*)(9*:,7=9*)(,)*)(9*>=2B)&"2*%9)=%20.*Y"%*9H,1#79D*)(9
>"77"A&2'*>=2B)&"2*%9)=%20*)(9*:,7=9*"> r ,>)9%*)(9 for 7""#.
b&)(*,*%9B=%0&:9*>=2B)&"2D*$"=*1=0)*0#9B&>$*)(9*%9)=%2*)$#9.*Y"%*9H,1#79D
35
def fac(n: Int):: Int = if (n <= 0) 1 else n * fac(n - 1)
b&)("=)*)(9*%9)=%2*)$#9D*)(9*-B,7,*B"1#&79%*B"=7;2L)*:9%&>$*)(,)*)(9*)$#9*"> n * fac(n -
1) &0*,2 Int.
G>*$"=*0=##7$*>9A9%*,%'=192)0*)(,2*)(9%9*,%9*#,%,19)9%0D*)(9*;9>,=7)0*,%9*,##7&9;*>%"1
)(9*92;.*Y"%*9H,1#79D decorate("Hello", ">>>[") =090*)(9*;9>,=7)*:,7=9*">*)(9
right #,%,19)9%D*$&97;&2' ">>>[Hello]".
c"=*B,2*,70"*=09*)(9*#,%,19)9%*2,190*A(92*$"=*0=##7$*)(9*,%'=192)0.*Y"%*9H,1#79D
<(9*%90=7)*&0 "<<<Hello>>>".*f")9*)(,)*)(9*2,19;*,%'=192)0*299;*2")*C9*&2*)(9*0,19
"%;9%*,0*)(9*#,%,19)9%0.
f,19;*,%'=192)0*B,2*1,E9*,*>=2B)&"2*B,77*1"%9*%9,;,C79.*<(9$*,%9*,70"*=09>=7*&>*,
>=2B)&"2*(,0*1,2$*;9>,=7)*#,%,19)9%0.
c"=*B,2*1&H*=22,19;*,2;*2,19;*,%'=192)0D*#%":&;9;*)(9*=22,19;*"290*B"19*>&%0)R
33
2.8. Variable Arguments (L1)
-"19)&190D*&)*&0*B"2:92&92)*)"*&1#79192)*,*>=2B)&"2*)(,)*B,2*),E9*,*:,%&,C79*2=1C9%*">
,%'=192)0.*<(9*>"77"A&2'*9H,1#79*0("A0*)(9*0$2),HR
c"=*B,77*)(9*>=2B)&"2*A&)(*,0*1,2$*,%'=192)0*,0*$"=*7&E9.
G>*$"=*,7%9,;$*(,:9*,*09K=92B9*">*:,7=90D*$"=*B,22")*#,00*&)*;&%9B)7$*)"*0=B(*,*>=2B)&"2.
Y"%*9H,1#79D*)(9*>"77"A&2'*&0*2")*B"%%9B)R
<(&0*0$2),H*&0*299;9;*&2*,*%9B=%0&:9*;9>&2&)&"2R
3X
Caution: b(92*$"=*B,77*,*?,:,*19)(";*A&)(*:,%&,C79*,%'=192)0*">*)$#9
ObjectD*0=B(*,0 PrintStream.printf "% MessageFormat.formatD*)(92*$"=*299;
)"*B"2:9%)*#%&1&)&:9*)$#90*C$*(,2;.*Y"%*9H,1#79D
2.9. Procedures
-B,7,*(,0*,*0#9B&,7*2"),)&"2*>"%*,*>=2B)&"2*)(,)*%9)=%20*2"*:,7=9.*G>*)(9*>=2B)&"2*C";$*&0
92B7"09;*&2*C%,B90 without a preceding =symbolD*)(92*)(9*%9)=%2*)$#9*&0 Unit.*-=B(*,
>=2B)&"2*&0*B,779;*, procedure.*6*#%"B9;=%9*%9)=%20*2"*:,7=9D*,2;*$"=*"27$*B,77*&)*>"%*&)0
0&;9*9>>9B).*Y"%*9H,1#79D*)(9*>"77"A&2'*#%"B9;=%9*#%&2)0*,*0)%&2'*&20&;9*,*C"HD*7&E9
-------
|Hello|
-------
V9B,=09*)(9*#%"B9;=%9*;"902L)*%9)=%2*,2$*:,7=9D*A9*"1&)*)(9 = 0$1C"7.
-"19*#9"#79*M2")*19N*;&07&E9*)(&0*B"2B&09*0$2),H*>"%*#%"B9;=%90*,2;*0=''90)*)(,)*$"=
,7A,$0*=09*,2*9H#7&B&)*%9)=%2*)$#9*"> UnitR
3Z
2.10. Lazy Values (L1)
b(92*, val &0*;9B7,%9;*,0 lazyD*&)0*&2&)&,7&p,)&"2*&0*;9>9%%9;*=2)&7*&)*&0*,BB9009;*>"%*)(9*>&%0)
)&19.*Y"%*9H,1#79D
Mb9*A&77*;&0B=00*>&79*"#9%,)&"20*&2 )(9*nY&790*,2;*89'=7,%*WH#%900&"20o*B(,#)9%.*Y"%*2"AD
I=0)*),E9*&)*>"%*'%,2)9;*)(,)*)(&0*B,77*%9,;0*,77*B(,%,B)9%0*>%"1,*>&79*&2)"*,*0)%&2'.N
G>*)(9*#%"'%,1*29:9%*,BB90090 wordsD*)(9*>&79*&0*29:9%*"#929;.*<"*:9%&>$*)(&0D*)%$*&)*"=)*&2
)(9*8WSTD*C=)*1&00#977*)(9*>&79*2,19.*<(9%9*A&77*C9*2"*9%%"%*A(92*)(9*&2&)&,7&p,)&"2
0),)9192)*&0*9H9B=)9;.*/"A9:9%D*A(92*$"=*,BB900 wordsD*$"=*A&77*'9)*,2*9%%"%*1900,'9
)(,)*)(9*>&79*&0*2")*>"=2;.
T,p$*:,7=90*,%9*=09>=7*)"*;97,$*B"0)7$*&2&)&,7&p,)&"2*0),)9192)0.*<(9$*B,2*,70"*;9,7*A&)(
")(9%*&2&)&,7&p,)&"2*&00=90D*0=B(*,0*B&%B=7,%*;9#92;92B&90.*P"%9":9%D*)(9$*,%9*90092)&,7*>"%
;9:97"#&2'*7,p$*;,),*0)%=B)=%90h099*)(9*-)%9,10*09B)&"2*&2 )(9*n!"779B)&"20o*B(,#)9%.
2.11. Exceptions
-B,7,*9HB9#)&"20*A"%E*)(9*0,19*A,$*,0*&2*?,:,*"%*!@@.*b(92*$"=*)(%"A*,2*9HB9#)&"2D
>"%*9H,1#79
)(92*)(9*B=%%92)*B"1#=),)&"2*&0*,C"%)9;D*,2;*)(9*%=2)&19*0$0)91*7""E0*>"%*,2*9HB9#)&"2
(,2;79%*)(,)*B,2*,BB9#)*,2 IllegalArgumentException.*!"2)%"7*%90=190*A&)(*)(9
&229%1"0)*0=B(*(,2;79%.*G>*2"*0=B(*(,2;79%*9H&0)0D*)(9*#%"'%,1*)9%1&2,)90.
3[
60*&2*?,:,D*)(9*"CI9B)0*)(,)*$"=*)(%"A*299;*)"*C97"2'*)"*,*0=CB7,00*">
java.lang.Throwable.*/"A9:9%D*=27&E9*?,:,D*-B,7,*(,0*2"*nB(9BE9;o*9HB9#)&"20h$"=
29:9%*299;*)"*;9B7,%9*)(,)*,*>=2B)&"2*"%*19)(";*1&'()*)(%"A*,2*9HB9#)&"2.
Note: G2*?,:,D*nB(9BE9;o*9HB9#)&"20*,%9*B(9BE9;*,)*B"1#&79J)&19.*G>*$"=%
19)(";*1&'()*)(%"A*,2 IOExceptionD*$"=*1=0)*;9B7,%9*&).*<(&0*>"%B90
#%"'%,119%0*)"*)(&2E*A(9%9*)("09*9HB9#)&"20*0("=7;*C9*(,2;79;D*A(&B(*&0*,
7,=;,C79*'",7.*e2>"%)=2,)97$D*&)*B,2*,70"*'&:9*%&09*)"*1"20)%"=0*19)(";
0&'2,)=%90*0=B(*,0 void doSomething() throws IOException,
InterruptedException, ClassNotFoundException.*P,2$*?,:,*#%"'%,119%0
;9)90)*)(&0*>9,)=%9*,2;*92;*=#*;9>9,)&2'*&)*C$*9&)(9%*B,)B(&2'*9HB9#)&"20*)""
9,%7$*"%*=0&2'*9HB900&:97$*'929%,7*9HB9#)&"2*B7,0090. <(9*-B,7,*;90&'29%0
;9B&;9;*,',&20)*B(9BE9;*9HB9#)&"20D*%9B"'2&p&2'*)(,)*)("%"='(*B"1#&79J)&19
B(9BE&2'*&02L) always ,*'"";*)(&2'.
if (x >= 0) sqrt(x)
else throw new IllegalArgumentException("x should not be negative")
<(9*0$2),H*>"%*B,)B(&2'*9HB9#)&"20*&0*1";979;*,>)9%*)(9*#,))9%2*1,)B(&2'*0$2),H*M099 )(9
nS,))9%2*P,)B(&2'*,2;*!,09*!7,0090o*B(,#)9%N.
try {
process(new FileReader(filename))
} catch {
case _: FileNotFoundException => println(filename + " not found")
case ex: IOException => ex.printStackTrace()
}
60*&2*?,:,*"%*!@@D*)(9*1"%9*'929%,7*9HB9#)&"2*)$#90*0("=7;*B"19*7,)9%*)(,2*)(9*1"%9
0#9B&>&B*"290.
f")9*)(,)*$"=*B,2*=09 _ >"%*)(9*:,%&,C79*2,19*&>*$"=*;"2L)*299;*&).
3\
val reader = new FileReader(filename)
try {
process(reader)
} finally {
reader.close()
}
<(&0*B";9*&0*,*C&)*0=C)79D*,2;*&)*%,&090*09:9%,7*&00=90.
<(&0*&0*)(9*0,19*,0
/"A9:9%D*)(,)*B"1C&2,)&"2*&0*%,%97$*=09>=7.
2.12. Exercises
5. <(9 signum ">*,*2=1C9%*&0*5*&>*)(9*2=1C9%*&0*#"0&)&:9D*J5*&>*&)*&0*29',)&:9*,2;*4*&>
&)*&0*p9%".*b%&)9*,*>=2B)&"2*)(,)*B"1#=)90*)(&0*:,7=9.
3. b(,)*&0*)(9*:,7=9*">*,2*91#)$*C7"BE*9H#%900&"2 {}g*b(,)*&0*&)0*)$#9g
X. !"19*=#*A&)(*"29*0&)=,)&"2*A(9%9*)(9*,00&'2192) x = y = 1 &0*:,7&;*&2*-B,7,.
M/&2)R*S&BE*,*0=&),C79*)$#9*>"% x.N
Z. b%&)9*,*-B,7,*9K=&:,792)*>"%*)(9*?,:,*7""#
3]
[. b%&)9*,*#%"B9;=%9 countdown(n: Int) )(,)*#%&2)0*)(9*2=1C9%0*>%"1 n )"*4.
\. b%&)9*, for 7""#*>"%*B"1#=)&2'*)(9*#%";=B)*">*)(9*e2&B";9*B";90*">*,77*79))9%0*&2
,*0)%&2'.*Y"%*9H,1#79D*)(9*#%";=B)*">*)(9*B(,%,B)9%0*&2 "Hello" &0*^3[5[3^_\.
]. -"7:9*)(9*#%9B9;&2'*9H9%B&09*A&)("=)*A%&)&2'*,*7""#.*M/&2)R*T""E*,)*)(9 StringOps
-B,7,;"B.N
^. b%&)9*,*>=2B)&"2 product(s : String) )(,)*B"1#=)90*)(9*#%";=B)D*,0*;90B%&C9;*&2
)(9*#%9B9;&2'*9H9%B&090.
_. P,E9*)(9*>=2B)&"2*">*)(9*#%9B9;&2'*9H9%B&09*,*%9B=%0&:9*>=2B)&"2.
54. b%&)9*,*>=2B)&"2*)(,)*B"1#=)90 xnD*A(9%9 n &0*,2*&2)9'9%.*e09*)(9*>"77"A&2'
%9B=%0&:9*;9>&2&)&"2R
x4 r*5
3^
3. Working With Arrays (A1)
G2*)(&0*B(,#)9%D*$"=*A&77*79,%2*("A*)"*A"%E*A&)(*,%%,$0*&2*-B,7,.*?,:,*,2;*!@@
#%"'%,119%0*=0=,77$*B(""09*,2*,%%,$*"%*,*B7"09*%97,)&"2*M&.9.D*,%%,$*7&0)0*"%*:9B)"%0N*A(92
)(9$*299;*)"*B"779B)*,*C=2B(*">*979192)0.*G2*-B,7,D*)(9%9*,%9*")(9%*B("&B90*M099 )(9
n!"779B)&"20o*B(,#)9%ND*C=)*>"%*2"AD*GL77*,00=19*)(,)*$"=*,%9*&1#,)&92)*,2;*I=0)*A,2)*)"*'9)
'"&2'*A&)(*,%%,$0.
a9$*#"&2)0*">*)(&0*B(,#)9%R
3_
import collection.mutable.ArrayBuffer
val b = ArrayBuffer[Int]()
// Q% new ArrayBuffer[Int]
// 62*91#)$*,%%,$*C=>>9%D*%9,;$*)"*("7;*&2)9'9%0
b += 1
// ArrayBuffer(1)
// 6;;*,2*979192)*,)*)(9*92;*A&)( +=
b += (1, 2, 3, 5)
// ArrayBuffer(1, 1, 2, 3, 55)
// 6;;*1,2$*979192)0*,)*)(9*92;*C$*92B7"0&2'*)(91*&2*#,%92)(9090
b ++= Array(8, 11, 17)
// ArrayBuffer(1, 1, 2, 3, 5, 8, 11, 17 17)
// c"=*B,2*,##92;*,2$*B"779B)&"2*A&)(*)(9 ++= "#9%,)"%
b.trimEnd(2)
// ArrayBuffer(1, 1, 2, 3, 5, 8)
// 891":90*)(9*7,0)*)A"*979192)0
6;;&2'*"%*%91":&2'*979192)0*,)*)(9*92;*">*,2*,%%,$*C=>>9%*&0*,2*9>>&B&92)*Mn,1"%)&p9;
B"20),2)*)&19oN*"#9%,)&"2.
c"=*B,2*,70"*&209%)*,2;*%91":9*979192)0*,)*,2*,%C&)%,%$*7"B,)&"2D*C=)*)("09*"#9%,)&"20*,%9
2")*,0*9>>&B&92)h,77*979192)0*,>)9%*)(,)*7"B,)&"2*1=0)*C9*0(&>)9;.*Y"%*9H,1#79R
b.insert(2, 6)
// ArrayBuffer(1, 1, 6, 2)
// G209%)*C9>"%9*&2;9H*3
b.insert(2, 7, 8, 99)
// ArrayBuffer(1, 1, 7, 8, 99, 6, 2)
// c"=*B,2*&209%)*,0*1,2$*979192)0*,0*$"=*7&E9
b.remove(2)
// ArrayBuffer(1, 1, 8, 9, 6, 2)
b.remove(2, 3)
// ArrayBuffer(1, 1, 2)
// <(9*09B"2;*#,%,19)9%*)9770*("A*1,2$*979192)0*)"*%91":9
-"19)&190D*$"=*A,2)*)"*C=&7;*=#*,2 ArrayD*C=)*$"=*;"2L)*$9)*E2"A*("A*1,2$*979192)0
$"=*A&77*299;.*G2*)(,)*B,09D*>&%0)*1,E9*,2*,%%,$*C=>>9%D*)(92*B,77
b.toArray
// Array(1, 1, 2)
X4
3.3. Traversing Arrays (and Array Buffers)
G2*?,:,*,2;*!@@D*)(9%9*,%9*09:9%,7*0$2),B)&B,7*;&>>9%92B90*C9)A992*,%%,$0*,2;*,%%,$*7&0)i
:9B)"%.*-B,7,*&0*1=B(*1"%9*=2&>"%1.*P"0)*">*)(9*)&19D*$"=*B,2*=09*)(9*0,19*B";9*>"%
C")(.
0 until 10
// Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
<(9*B"20)%=B)
<"*:&0&)*9:9%$*09B"2;*979192)D*79) i )%,:9%09
0 until (a.size, 2)
// Range(0, 2, 4, ...)
<"*:&0&)*)(9*979192)0*0),%)&2'*>%"1*)(9*92;*">*)(9*,%%,$D*)%,:9%09
(0 until a.size).reverse
// Range(..., 2, 1, 0)
G>*$"=*;"2L)*299;*)(9*,%%,$*&2;9H*&2*)(9*7""#*C";$D*:&0&)*)(9*,%%,$*979192)0*;&%9B)7$D*7&E9
)(&0R
X5
<(&0*&0*:9%$*0&1&7,%*)"*)(9*n92(,2B9;ofor 7""#*&2*?,:,*"%*)(9*n%,2'9JC,09;o for 7""#*&2
!@@.*<(9*:,%&,C79 elem &0*09)*)" a(0)D*)(92 a(1)D*,2;*0"*"2.
<(9*%90=7)*B"2),&20*)(9*9H#%900&"20*,>)9%*)(9 yieldD*"29*>"%*9,B(*&)9%,)&"2*">*)(9*7""#.
Q>)92*)&190D*A(92*$"=*)%,:9%09*,*B"779B)&"2D*$"=*"27$*A,2)*)"*#%"B900*)(9*"290*)(,)*1,)B(
,*#,%)&B=7,%*B"2;&)&"2.*<(&0*&0*,B(&9:9;*A&)(*, guardR*,2 if &20&;9*)(9 for.*/9%9*A9*%9)=%2
"27$*)(9*9:92*979192)0R
62;*(9%9*A9*;"=C79*9:9%$*9:92*979192)D*0)&77*;%"##&2'*)(9*";;*"290R
a99#*&2*1&2;*)(,)*)(9*%90=7)*&0*,*29A*B"779B)&"2h)(9*"%&'&2,7*B"779B)&"2*&0*2")*,>>9B)9;.
Note: 67)9%2,)&:97$D*$"=*B"=7;*A%&)9
b.filter(_ % 2 == 0).map(2 * _)
"%*9:92
b filter { _ % 2 == 0 } map { 2 * _ }
X3
-"19*#%"'%,119%0*A&)(*9H#9%&92B9*&2*>=2B)&"2,7*#%"'%,11&2'*#%9>9% filter
,2; map &20)9,;*">*'=,%;0*,2; yield.*<(,)L0*I=0)*,*1,))9%*">*0)$79h)(9 for 7""#
;"90*9H,B)7$*)(9*0,19*A"%E.*e09*A(,)9:9%*$"=*>&2;*9,0&9%.
!"20&;9%*)(9*>"77"A&2'*9H,1#79.*t&:92*,*09K=92B9*">*&2)9'9%0D*A9*A,2)*)"*%91":9*,77*C=)
)(9*>&%0)*29',)&:9*2=1C9%.*6*)%,;&)&"2,7*09K=92)&,7*0"7=)&"2*A"=7;*09)*,*>7,'*A(92*)(9*>&%0)
29',)&:9*2=1C9%*&0*B,779;D*)(92*%91":9*,77*979192)0*C9$"2;.
V=)*A,&)h)(,)L0*,B)=,77$*2")*0"*'"";.*G)L0*&29>>&B&92)*)"*%91":9*:,%&,C790*>%"1*)(9*>%"2).
b9*0("=7;*0),%)*>%"1*)(9*C,BE*,>)9%*>&2;&2'*)(9*>&%0)*1,)B(.
<(92*A9*:&0&)*)(9*&2;9H90*&2*%9:9%09D*9HB9#)*>"% indexes(0).
Array(1, 7, 2, 9).sum
// 19
// b"%E0*>"% ArrayBuffer )""
XX
G2*"%;9%*)"*=09*)(9 sum 19)(";D*)(9*979192)*)$#9*1=0)*C9*,*2=19%&B*)$#9R*,2*&2)9'%,7*"%
>7",)&2'J#"&2)*)$#9D*"% BigIntegeriBigDecimal.
val b = ArrayBuffer(1, 7, 2, 9)
val bSorted = b.sortWith(_ < _)
// b &0*=2B(,2'9;F bSorted &0 ArrayBuffer(1, 2, 7, 9)
c"=*#,00*)(9*B"1#,%&0"2*>=2B)&"2*,0*,*#,%,19)9%h099 )(9*n/&'(9%*Q%;9%*Y=2B)&"20o
B(,#)9% >"%*)(9*>=2B)&"2*0$2),H.
c"=*B,2*0"%)*,2*,%%,$D*C=)*2")*,2*,%%,$*C=>>9%D*&2*#7,B9R
val a = Array(1, 7, 2, 9)
util.Sorting.quickSort(a)
// a &0*2"A Array(1, 2, 7, 9)
Y&2,77$D*&>*$"=*A,2)*)"*;&0#7,$*)(9*B"2)92)0*">*,2*,%%,$*"%*,%%,$*C=>>9%D*)(9
mkString 19)(";*79)0*$"=*0#9B&>$*)(9*09#,%,)"%*C9)A992*979192)0.*6*09B"2;*:,%&,2)*(,0
#,%,19)9%0*>"%*)(9*#%9>&H*,2;*0=>>&H.*Y"%*9H,1#79D
!"2)%,0)*A&)( toStringR
a.toString
// "[I@b73e5"
// <(&0*&0*)(9*=097900 toString 19)(";*>%"1*?,:,
b.toString
// "ArrayBuffer(1, 7, 2, 9)"
// <(9 toString 19)(";*B"2),&20*)(9*)$#9D*A(&B(*&0*=09>=7*>"%*;9C=''&2'
XZ
3.6. Deciphering ScalaDoc
<(9%9*,%9*7")0*">*=09>=7*19)(";0*"2*,%%,$0*,2;*,%%,$*7&0)0D*,2;*&)*&0*,*'"";*&;9,*)"*C%"A09
)(9*-B,7,*;"B=192),)&"2*)"*'9)*,2*&;9,*A(,)L0*)(9%9.
V9B,=09*-B,7,*(,0*%&B(9%*)$#9*0$0)91*)(,2*?,:,D*$"=*1,$*92B"=2)9%*0"19*0)%,2'9J7""E&2'
0$2),H*,0*$"=*C%"A09*)(9*-B,7,*;"B=192),)&"2.*Y"%)=2,)97$D*$"=*;"2L)*(,:9*)"*=2;9%0),2;
,77*2=,2B90*">*)(9*)$#9*0$0)91*)"*;"*=09>=7*A"%E.*e09 <,C79*5 ,0*,*n;9B";9%*%&2'o.
<,C79*XJ5R -B,7,U"B*U9B";9%*8&2'
ScalaDoc Explanation
<(&0*19)(";*),E90*, predicateD*,*>=2B)&"2*>%"1*6*)"
def count (p:
p: (A) => V""79,2.*G)*B"=2)0*>"%*("A*1,2$*979192)0*)(9*>=2B)&"2
Boolean
Boolean) : Int &0*)%=9.*Y"%*9H,1#79D a.count(_ > 0) B"=2)0*("A*1,2$
979192)0*"> a ,%9*#"0&)&:9.
<(&0*19)(";*),E90 zero or more ,%'=192)0*">*)$#9 A.*Y"%
def append (elems: A*
A*) :
9H,1#79D a.append(1, 7, 2, 9) ,##92;0*>"=%*979192)0
Unit
)" a.
<(9 xs #,%,19)9%*B,2*C9*,2$*B"779B)&"2*A&)(*)(9
TraversableOnce )%,&)D*)(9*1"0)*'929%,7*)%,&)*&2*)(9*-B,7,
B"779B)&"20*(&9%,%B($.*Q)(9%*B"11"2*)%,&)0*)(,)*$"=*1,$
92B"=2)9%*&2*-B,7,U"B*,%9*,%9 Traversable ,2;
Iterable.*677*-B,7,*B"779B)&"20*&1#79192)*)(909*)%,&)0D
def appendAll (xs: ,2;*)(9*;&>>9%92B9*C9)A992*)(91*&0*,B,;91&B*>"%*7&C%,%$
TraversableOnce[A]
TraversableOnce[A]) : Unit =09%0.*-&1#7$*)(&2E*n,2$*B"779B)&"2o*A(92*$"=*099*"29
">*)(909.
X[
b(92*$"=*A"%E*A&)(*,2 ArrayBuffer[A]D*$"=*B,2*I=0)
)(&2E*">*)(9*19)(";*,0 def += (elem: A) :
ArrayBuffer[A].
G>*0"19"29*>"%10*,*0=CB7,00*"> ArrayBufferD*)(92*)(9
%9)=%2*)$#9*"> += &0*)(,)*0=CB7,00.
f")9*)(,)*)(9*>=2B)&"2*B"#&90*,2 ArrayBuffer[A]
[A] &2)"*,2
Array[B]
[B].*/9%9D*V*&0*,77"A9;*)"*C9*, supertype ">*6.*Y"%
9H,1#79D*$"=*B,2*B"#$*>%"1*,2 ArrayBuffer[Int] )"*,2
def copyToArray [B >: A] Array[Any].
(xs: Array[B]
Array[B]) : Unit
6)*>&%0)*%9,;&2'D*I=0)*&'2"%9*)(9 [B >: A] ,2;*%9#7,B9 B
A&)( A.
A 1=0)*(,:9*,*0=#9%)$#9 B >"%*A(&B(*,2*n&1#7&B&)o*"CI9B)
def max [B >: A] (implicit
">*)$#9 Ordering[B] 9H&0)0.*-=B(*,2*"%;9%&2'*9H&0)0*>"%
cmp: Ordering[B]) : A
2=1C9%0D*0)%&2'0D*,2;*")(9%*)$#90*A&)(*)(9 Ordered )%,&).
<(&0*;9B7,%,)&"2*(,##920*A(92*)(9*19)(";*B%9,)90*,
29A*B"779B)&"2.*-E&#*&)*,2;*7""E*>"%*)(9*0&1#79%
def padTo [B >: A, That
That] ,7)9%2,)&:9D*&2*)(&0*B,09
(len: Int, elem: B)(implicit
(implicit
bf: def padTo (len: Int, elem: A) : ArrayBuffer[A]
CanBuildFrom[ArrayBuffer[A],
B, That]) : That 6*>=)=%9*:9%0&"2*">*-B,7,;"B*A&77*(&;9*)(909
;9B7,%,)&"20.
<"*,BB900*,2*979192)D*$"=*=09*)A"*#,&%0*">*#,%92)(9090R
matrix(row)(column) = 42
X\
3.8. Interoperating with Java
-&2B9*-B,7,*,%%,$0*,%9*&1#79192)9;*,0*?,:,*,%%,$0D*$"=*B,2*#,00*)(91*C,BE*,2;*>"%)(
C9)A992*?,:,*,2;*-B,7,.
G>*$"=*B,77*,*?,:,*19)(";*)(,)*%9B9&:90*"%*%9)=%20*, java.util.ListD*$"=*B"=7;*">*B"=%09
=09*,*?,:, ArrayList &2*$"=%*-B,7,*B";9D*C=)*)(,)*&0*=2,))%,B)&:9.*G20)9,;D*&1#"%)*)(9
&1#7&B&)*B"2:9%0&"2*19)(";0*&2 collection.JavaConversions.*<(92*$"=*B,2*=09*-B,7,
C=>>9%0*&2*$"=%*B";9D*,2;*)(9$*,=)"1,)&B,77$*'9)*A%,##9;*&2)"?,:,*7&0)0*A(92*B,77&2'*,
?,:,*19)(";.
import collection.JavaConversions.asJavaList
// Q%*0&1#7$ import collection.JavaConversions._
val commands = collection.mutable.ArrayBuffer("ls", "-al", "/home/cay")
val pb = new ProcessBuilder(commands)
<(9*-B,7,*C=>>9%*&0*A%,##9;*&2)"*,2*"CI9B)*">*,*?,:,*B7,00*)(,)*&1#79192)0*)(9
java.util.List &2)9%>,B9.
!"2:9%097$D*A(92*,*?,:,*19)(";*%9)=%20*, java.util.ListD*$"=*B,2*(,:9*&)*,=)"1,)&B,77$
B"2:9%)9;*&2)"*, BufferR
import collection.JavaConversions.asScalaBuffer
val cmds : collection.mutable.Buffer[String] = pb.commands()
// c"=*B,2L)*=09 ArrayBufferh)(9*A%,##9;*"CI9B)*&0*"27$*'=,%,2)99;*)"*C9*, Buffer
G>*)(9*?,:,*19)(";*%9)=%20*,*A%,##9;*-B,7,*C=>>9%D*)(92*)(9*&1#7&B&)*B"2:9%0&"2*=2A%,#0
)(9*"%&'&2,7*"CI9B).*G2*"=%*9H,1#79D cmds == commands.
<(9*9H#7&B&)*#,BE,'9*2,190*1,E9*)(9*0,1#79*B";9*1"%9*B"1#79H*)(,2*A(,)*$"=*A"=7;
;"*&2*#%,B)&B9.*b&)(*)(9*&1#"%)0
import collection.JavaConversions._
import collection.mutable.Buffer
A9*(,:9
X]
3.9. Exercises
5. b%&)9*,*B";9*02&##9)*)(,)*09)0 a )"*,2*,%%,$*"> n %,2;"1*&2)9'9%0*C9)A992*4
M&2B7=0&:9N*,2; n M9HB7=0&:9N.
3. b%&)9*,*7""#*)(,)*0A,#0*,;I,B92)*979192)0*">*,2*,%%,$*">*&2)9'9%0.*Y"%*9H,1#79D
Array(1, 2, 3, 4, 5) C9B"190 Array(2, 1, 4, 3, 5).
X. 89#9,)*)(9*#%9B9;&2'*,00&'2192)D*C=)*#%";=B9*,*29A*,%%,$*A&)(*)(9*0A,##9;
:,7=90.*e09 foriyield.
Z. t&:92*,2*,%%,$*">*&2)9'9%0D*#%";=B9*,*29A*,%%,$*)(,)*B"2),&20*,77*#"0&)&:9*:,7=90
">*)(9*"%&'&2,7*,%%,$D*&2*)(9&%*"%&'&2,7*"%;9%D*>"77"A9;*C$*,77*:,7=90*)(,)*,%9*p9%"*"%
29',)&:9D*&2*)(9&%*"%&'&2,7*"%;9%.
[. /"A*;"*$"=*B"1#=)9*)(9*,:9%,'9*">*,2 Array[Double]g
\. /"A*;"*$"=*%9,%%,2'9*)(9*979192)0*">*,2 Array[Int] 0"*)(,)*)(9$*,##9,%*&2
%9:9%09*0"%)9;*"%;9%g*/"A*;"*$"=*;"*)(9*0,19*A&)(*,2 ArrayBuffer[Int]g
]. b%&)9*,*B";9*02&##9)*)(,)*#%";=B90*,77*:,7=90*>%"1*,2*,%%,$*A&)(*;=#7&B,)90
%91":9;.*M/&2)R*T""E*,)*-B,7,U"BN
^. 89A%&)9*)(9*9H,1#79*,)*)(9*92;*"> -9B)&"2*Z =0&2'*)(9 drop 19)(";*>"%*;%"##&2'
)(9*&2;9H*">*)(9*>&%0)*1,)B(.*T""E*)(9*19)(";*=#*&2*-B,7,U"B.
_. P,E9*,*B"779B)&"2*">*,77*)&19*p"290*%9)=%29;*C$
java.util.TimeZone.getAvailableIds )(,)*,%9*&2*619%&B,.*-)%&#*">>*)(9
"America/" #%9>&H*,2;*0"%)*)(9*%90=7).
54. G1#"%) java.awt.datatransfer._ ,2;*1,E9*,2*"CI9B)*">*)$#9 SystemFlavorMap
A&)(*)(9*B,77
X^
4. Maps and Tuples (A1)
6*B7,00&B*#%"'%,119%L0*0,$&2'*&0*nG>*G*B,2*"27$*(,:9*"29*;,),*0)%=B)=%9D*1,E9*&)*,*(,0(
),C79o.*/,0(*),C790D*"%*1"%9*'929%,77$D*1,#0D*,%9*,1"2'*)(9*1"0)*:9%0,)&79*;,),*0)%=B)=%90.
60*$"=*A&77*099*&2*)(&0*B(,#)9%D-B,7,*1,E90*&)*#,%)&B=7,%7$*9,0$*)"*=09*)(91.
P,#0*,%9*,*B"779B)&"2*">*E9$i:,7=9*#,&%0.*-B,7,*(,0*,*'929%,7*2"),)&"2*">*)=#790D
,''%9',)90*"> n "CI9B)0D*2")*29B900,%&7$*">*)(9*0,19*)$#9.*6*#,&%*&0*0&1#7$*,*)=#79*A&)( n r
3.*<=#790*,%9*=09>=7*A(929:9%*$"=*299;*)"*,''%9',)9*)A"*"%*1"%9*:,7=90*)"'9)(9%D*,2;*A9
C%&9>7$*;&0B=00*)(9*0$2),H*,)*)(9*92;*">*)(&0*B(,#)9%.
/&'(7&'()0*">*)(9*B(,#)9%*,%9R
d -B,7,*(,0*,*#79,0,2)*0$2),H*>"%*B%9,)&2'D*K=9%$&2'D*,2;*)%,:9%0&2'*1,#0
d c"=*299;*)"*B(""09*C9)A992*1=),C79*,2;*&11=),C79*1,#0
d V$*;9>,=7)D*$"=*'9)*,*(,0(*1,#D*C=)*$"=*B,2*,70"*'9)*,*)%99*1,#
d c"=*B,2*9,0&7$*B"2:9%)*C9)A992*-B,7,*,2;*?,:,*1,#0
d <=#790*,%9*=09>=7*>"%*,''%9',)&2'*:,7=90
G>*$"=*A,2)*)"*0),%)*"=)*A&)(*,*C7,2E*1,#D*$"=*(,:9*)"*#&BE*,*1,#*&1#79192),)&"2*,2;
0=##7$*)$#9*#,%,19)9%0R
G2*-B,7,D*,*1,#*&0*,*B"779B)&"2*"> pairs.*6*#,&%*&0*0&1#7$*,*'%"=#&2'*">*)A"*:,7=90D*2")
29B900,%&7$*">*)(9*0,19*)$#9D*0=B(*,0 ("Alice", 10).
"Alice" -> 10
&0
X_
("Alice", 10)
c"=*B"=7;*(,:9*9K=,77$*A977*;9>&29;*)(9*1,#*,0
G>*)(9*1,#*;"902L)*B"2),&2*,*:,7=9*>"%*)(9*%9K=90)9;*E9$D*,2*9HB9#)&"2*&0*)(%"A2.
V9B,=09*)(&0*B,77*B"1C&2,)&"2*&0*0"*B"11"2D*)(9%9*&0*,*0("%)B=)R
67)9%2,)&:97$D*$"=*B,2*=09*)(9 += "#9%,)&"2*)"*,;;*1=7)O*,00"B&,)&"20R
c"=*%91":9*,*E9$*,2;*&)0*,00"B&,)9;*:,7=9*A&)(*)(9 -= "#9%,)"%R
Z4
scores -= "Alice"
c"=*B,2L)*=#;,)9*,2*&11=),C79*1,#D*C=)*$"=*B,2*;"*0"19)(&2'*)(,)L0*I=0)*,0
=09>=7h"C),&2*,*29A*1,#*)(,)*(,0*)(9*;90&%9;*=#;,)9.
G20)9,;*">*0,:&2'*)(9*%90=7)*,0*,*29A*:,7=9D*$"=*B,2*=#;,)9*, varR
-&1&7,%7$D*)"*%91":9*,*E9$*>%"1*,2*&11=),C79*1,#D*$"=*=09*)(9 - "#9%,)"%*)"*"C),&2*,
29A*1,#*A&)("=)*)(9*E9$R
c"=*1&'()*)(&2E*)(,)*&)*&0*&29>>&B&92)*)"*E99#*B"20)%=B)&2'*29A*1,#0D*C=)*)(,)*&0*2")*)(9
B,09.*<(9*"7;*,2;*29A*1,#*0(,%9*1"0)*">*)(9&%*0)%=B)=%9.*M<(&0*&0*#"00&C79*C9B,=09*)(9$
,%9*&11=),C79.N
<"*%9:9%09*,*1,#D*)(,)*&0D*0A&)B(*E9$0*,2;*:,7=90D*=09
Z5
4.5. Hash Tables and Trees
b(92*A"%E&2'*A&)(*,*1,#D*$"=*299;*)"*B(""09*,2*&1#79192),)&"2h,*(,0(*),C79*"%*,
C,7,2B9;*)%99.*V$*;9>,=7)D*-B,7,*'&:90*$"=*,*(,0(*),C79.*c"=*1&'()*A,2)*,*)%99*1,#*&>*$"=
;"2L)*(,:9*,*'"";*(,0(*>=2B)&"2*>"%*)(9*E9$0D*"%*&>*$"=*299;*)"*:&0&)*)(9*E9$0*&2*0"%)9;
"%;9%.
V$*;9>,=7)D*-B,7,*'&:90*$"=*,*(,0(*1,#.*<"*'9)*,2*&11=),C79*)%99*1,#D*=09
e2>"%)=2,)97$D*)(9%9*&0*M,0*">*-B,7,*3._N*2"*1=),C79*)%99*1,#.*c"=%*C90)*C9)*&0*)"*,;,#)*,
?,:, TreeMapD*,0*;90B%&C9;*&2 )(9*n!"779B)&"20o*B(,#)9%.
-&1#7$*,;;*,2*&1#"%)*0),)9192)
import collection.JavaConversions.mapAsScalaMap
<(92*)%&''9%*)(9*B"2:9%0&"2*C$*0#9B&>$&2'*)(9*-B,7,*1,#*)$#9R
import collection.JavaConversions.propertiesAsScalaMap
val props: collection.Map[String, String] = System.getProperties()
Z3
!"2:9%097$D*)"*#,00*,*-B,7,*1,#*)"*,*19)(";*)(,)*9H#9B)0*,*?,:,*1,#D*#%":&;9*)(9
"##"0&)9*&1#7&B&)*B"2:9%0&"2.*Y"%*9H,1#79R
import collection.JavaConversions.mapAsJavaMap
import java.awt.font.TextAttribute._ // G1#"%)*E9$0*>"%*1,#*C97"A
val attrs = Map(FAMILY -> "Serif", SIZE -> 12) // 6*-B,7,*1,#
val font = new java.awt.Font(attrs) // WH#9B)0*,*?,:,*1,#
4.7. Tuples
P,#0*,%9*B"779B)&"20*">*E9$i:,7=9*#,&%0.*S,&%0*,%9*)(9*0&1#790)*B,09*"> tuplesD*,''%9',)90
">*:,7=90*">*;&>>9%92)*)$#90.
6*)=#79*:,7=9*&0*>"%19;*C$*92B7"0&2'*&2;&:&;=,7*:,7=90*&2*#,%92)(9090.*Y"%*9H,1#79D
&0*,*)=#79*">*)$#9
A(&B(*&0*,70"*A%&))92*,0
G>*$"=*(,:9*,*)=#79D*0,$D
e27&E9*,%%,$*"%*0)%&2'*#"0&)&"20D*)(9*B"1#"292)*#"0&)&"20*">*,*)=#79*0),%)*A&)(*5D*2")*4.
e0=,77$D*&)*&0*C9))9%*)"*=09*#,))9%2*1,)B(&2'*)"*'9)*,)*)(9*B"1#"292)0*">*,*)=#79D*>"%
9H,1#79
val (first, second, third) = t // -9)0 first )" 1D second )" 3.14D third )" "Fred"
ZX
<=#790*,%9*=09>=7*>"%*>=2B)&"20*)(,)*%9)=%2*1"%9*)(,2*"29*:,7=9.*Y"%*9H,1#79D*)(9
partition 19)(";*">*)(9 StringOps B7,00*%9)=%20*,*#,&%*">*0)%&2'0D*B"2),&2&2'*)(9
B(,%,B)9%0*)(,)*>=7>&77*,*B"2;&)&"2*,2;*)("09*)(,)*;"2L)R
4.8. Zipping
Q29*%9,0"2*>"%*=0&2'*)=#790*&0*)"*C=2;79*)"'9)(9%*:,7=90*0"*)(,)*)(9$*B,2*C9*#%"B9009;
)"'9)(9%.*<(&0*&0*B"11"27$*;"29*A&)(*)(9 zip 19)(";.*Y"%*9H,1#79D*)(9*B";9
$&97;0*,2*,%%,$*">*#,&%0
<(9*#,&%0*B,2*)(92*C9*#%"B9009;*)"'9)(9%R
G>*$"=*(,:9*,*B"779B)&"2*">*E9$0*,2;*,*#,%,7797*B"779B)&"2*">*:,7=90D*)(92*p&#
)(91*=#*,2;*)=%2*)(91*&2)"*,*1,#D*7&E9*)(&0R
keys.zip(values).toMap
4.9. Exercises
5. -9)*=#*,*1,#*">*#%&B90*>"%*,*2=1C9%*">*'&p1"0*)(,)*$"=*B":9).*<(92*#%";=B9*,
09B"2;*1,#*A&)(*)(9*0,19*E9$0*,2;*)(9*#%&B90*,)*,*54*#9%B92)*;&0B"=2).
3. b%&)9*,*#%"'%,1*)(,)*%9,;0*A"%;0*>%"1*,*>&79.*e09*,*1=),C79*1,#*)"*B"=2)*("A
">)92*9,B(*A"%;*,##9,%0.*<"*%9,;*)(9*A"%;0D*0&1#7$*=09*, java.util.ScannerR
ZZ
6)*)(9*92;D*#%&2)*"=)*,77*A"%;0*,2;*)(9&%*B"=2)0.
X. 89#9,)*)(9*#%9B9;&2'*9H9%B&09*A&)(*,2*&11=),C79*1,#.
Z. 89#9,)*)(9*#%9B9;&2'*9H9%B&09*A&)(*,*0"%)9;*1,#D*0"*)(,)*)(9*A"%;0*,%9*#%&2)9;*&2
0"%)9;*"%;9%.
[. 89#9,)*)(9*#%9B9;&2'*9H9%B&09*A&)(*, java.util.TreeMap )(,)*$"=*,;,#)*)"*)(9
-B,7,*6SG.
\. U9>&29*,*7&2E9;*(,0(*1,#*)(,)*1,#0 "Monday" )" java.util.Calendar.MONDAYD
,2;*0&1&7,%7$*>"%*)(9*")(9%*A99E;,$0.*U91"20)%,)9*)(,)*)(9*979192)0*,%9*:&0&)9;
&2*&209%)&"2*"%;9%.
]. S%&2)*,*),C79*">*,77*?,:,*#%"#9%)&90D*7&E9*)(&0R
c"=*299;*)"*>&2;*)(9*792')(*">*)(9*7"2'90)*E9$*C9>"%9*$"=*B,2*#%&2)*)(9*),C79.
Z[
5. Classes (A1)
G2*)(&0*B(,#)9%D*$"=*A&77*79,%2*("A*)"*&1#79192)*B7,0090*&2*-B,7,.*G>*$"=*E2"A*B7,0090*&2
?,:,*"%*!@@D*$"=*A"2L)*>&2;*)(&0*;&>>&B=7)D*,2;*$"=*A&77*92I"$*)(9*1=B(*1"%9*B"2B&09
2"),)&"2*">*-B,7,.
<(9*E9$*#"&2)0*">*)(&0*B(,#)9%*,%9R
d Y&97;0*&2*B7,0090*,=)"1,)&B,77$*B"19*A&)(*'9))9%0*,2;*09))9%0
d c"=*B,2*%9#7,B9*,*>&97;*A&)(*,*B=0)"1*'9))9%i09))9%*A&)("=)*B(,2'&2'*)(9*B7&92)*">
,*B7,00h)(,)*&0*)(9*n=2&>"%1*,BB900*#%&2BOo
d e09*)(9 @BeanProperty ,22"),)&"2*)"*'929%,)9*?,:,V9,20 getXxxisetXxx 19)(";0
d W:9%$*B7,00*(,0*,*#%&1,%$*B"20)%=B)"%*)(,)*&0*n&2)9%A":92o*A&)(*)(9*B7,00
;9>&2&)&"2.*G)0*#,%,19)9%0*)=%2*&2)"*>&97;0*">*)(9*B7,00.*<(9*#%&1,%$*B"20)%=B)"%
9H9B=)90*,77*0),)9192)0*&2*)(9*C";$*">*)(9*B7,00.
d 6=H&7&,%$*B"20)%=B)"%0*,%9*"#)&"2,7.*<(9$*,%9*B,779; this.
class Counter {
private var value: Int = 0 // c"= must &2&)&,7&p9*)(9*>&97;
def increment() { value += 1 } // P9)(";0*,%9*#=C7&B*C$*;9>,=7)
def current() = value
}
G2*-B,7,D*,*B7,00*&0*2")*;9B7,%9;*,0 public.*6*-B,7,*0"=%B9*>&79*B,2*B"2),&2*1=7)O
B7,0090D*,2;*,77*">*)(91*(,:9*#=C7&B*:&0&C&7&)$.
<"*=09*)(&0*B7,00D*$"=*B"20)%=B)*"CI9B)0*,2;*&2:"E9*19)(";0*&2*)(9*=0=,7*A,$R
c"=*B,2*B,77*,*#,%,19)9%J7900*19)(";*M0=B(*,0 currentN*A&)("=)*"%*A&)(*#,%92)(9090R
myCounter.current // QE
myCounter.current() // 670"*"E
Z\
b(&B(*>"%1*0("=7;*$"=*=09g*G)*&0*B"20&;9%9;*'"";*0)$79*)"*=09 () >"%*, mutator 19)(";*M,
19)(";*)(,)*B(,2'90*)(9*"CI9B)*0),)9ND*,2;*)"*;%"#*)(9 () >"%*,2 accessor 19)(";*M,
19)(";*)(,)*;"90*2")*B(,2'9*)(9*"CI9B)*0),)9N.
<(,)L0*A(,)*A9*;&;*&2*"=%*9H,1#79R
myCounter.increment()
increment() // e09 () A&)(*1=),)"%
println(myCounter.current
current) // U"2L)*=09 () A&)(*,BB900"%
class Counter {
...
def current = value // f" () &2*;9>&2&)&"2
}
f"A*)(9*B7,00*=09%*1=0)*=09 myCounter.currentD*A&)("=)*#,%92)(9090.
b&)(*,*#=C7&B*>&97;D*,2$"29*B"=7;*A%&)9*)" fred.ageD*1,E&2'*Y%9;*$"=2'9%*"%*"7;9%.*<(,)L0
A($*A9*#%9>9%*)"*=09*'9))9%*,2;*09))9%*19)(";0R
6*'9))9%i09))9%*#,&%*0=B(*,0*)(&0*"29*&0*">)92*B,779;*, property.*b9*0,$*)(,)*)(9*B7,00
Person (,0*,2 age #%"#9%)$.
b($*&0*)(&0*,2$*C9))9%g*V$*&)097>D*&)*&02L).*62$"29*B,2*B,77 fred.setAge(21)D*E99#&2'*(&1
>"%9:9%*)A92)$J"29.
V=)*&>*)(,)*C9B"190*,*#%"C791D*A9*B,2*'=,%;*,',&20)*&)R
Z]
t9))9%0*,2;*09))9%0*,%9*C9))9%*)(,2*#=C7&B*>&97;0*C9B,=09*)(9$*79)*$"=*0),%)*A&)(*0&1#79*'9)i
09)*091,2)&B0*,2;*9:"7:9*)(91*,0*299;9;.
Note: ?=0)*C9B,=09*'9))9%0*,2;*09))9%0*,%9*C9))9%*)(,2*#=C7&B*>&97;0*;"902L)*19,2
)(9$*,%9*,7A,$0*'"";.*Q>)92D*&)*&0*#7,&27$*C,;*&>*9:9%$*B7&92)*B,2*'9)*"%*09)*C&)0
,2;*#&9B90*">*,2*"CI9B)L0*0),)9.*G2*)(&0*09B)&"2D*G*0("A*$"=*("A*)"*&1#79192)
#%"#9%)&90*&2*-B,7,.*G)*&0*=#*)"*$"=*)"*B(""09*A&097$*A(92*,*'9)),C79i09)),C79
#%"#9%)$*&0*,2*,##%"#%&,)9*;90&'2.
-B,7,*#%":&;90*'9))9%*,2;*09))9%*19)(";0*>"%*9:9%$*>&97;.*/9%9D*A9*;9>&29*,*#=C7&B*>&97;R
class Person {
var age: Int = 0
}
$ scalac Person.scala
$ scala -private Person
Compiled from "Person.scala"
public class Person extends java.lang.Object implements scala.ScalaObject{
private int age;
public int age();
public void age_$eq(int);
public Person();
}
Z^
Note: G2*-B,7,D*)(9*'9))9%0*,2;*09))9%0*,%9*2")*2,19; getXxx ,2; setXxxD*C=)
)(9$*>=7>&77*)(9*0,19*#=%#"09. -9B)&"2*[ 0("A0*("A*)"*'929%,)9*?,:,J0)$79
getXxx ,2; setXxx 19)(";0D*0"*)(,)*$"=%*-B,7,*B7,0090*B,2*&2)9%"#9%,)9*A&)(
?,:,*)""70.
6)*,2$*)&19D*$"=*B,2*%9;9>&29*)(9*'9))9%*,2;*09))9%*19)(";0*$"=%097>.*Y"%*9H,1#79D
class Person {
private var privateAge: Int = 0 // P,E9*#%&:,)9*,2;*%92,19
<(9*=09%*">*$"=%*B7,00*0)&77*,BB90090 fred.ageD*C=)*2"A*Y%9;*B,2L)*'9)*$"=2'9%R
Note: V9%)%,2;*P9$9%D*)(9*&2:92)"%*">*)(9*&2>7=92)&,7*W&>>97*7,2'=,'9D
>"%1=7,)9;*)(9 Uniform Access Principle )(,)*0),)90R*n677*09%:&B90*">>9%9;*C$*,
1";=79*0("=7;*C9*,:,&7,C79*)(%"='(*,*=2&>"%1*2"),)&"2D*A(&B(*;"90*2")*C9)%,$
A(9)(9%*)(9$*,%9*&1#79192)9;*)(%"='(*0)"%,'9*"%*)(%"='(*B"1#=),)&"2.o*G2
-B,7,D*)(9*B,779%*"> fred.age ;"902L)*E2"A*A(9)(9% age &0*&1#79192)9;
)(%"='(*,*>&97;*"%*,*19)(";.*MQ>*B"=%09D*&2*)(9*?sPD*)(9*09%:&B9*&0 always
&1#79192)9;*)(%"='(*,*19)(";D*9&)(9%*0$2)(90&p9;*"%*#%"'%,119%J0=##7&9;.N
Tip: G)*1,$*0"=2;*0B,%$*)(,)*-B,7,*'929%,)90*'9))9%*,2;*09))9%*19)(";0*>"%
9:9%$*>&97;.*V=)*$"=*(,:9*0"19*B"2)%"7*":9%*)(&0*#%"B900.
d G>*)(9*>&97;*&0*#%&:,)9D*)(9*'9))9%*,2;*09))9%*,%9*#%&:,)9
d G>*)(9*>&97;*&0*, valD*"27$*,*'9))9%*&0*'929%,)9;
d G>*$"=*;"2L)*A,2)*,2$*'9))9%*"%*09))9%D*;9B7,%9*)(9*>&97;*,0
private[this] M099 -9B)&"2*ZN
Z_
5.3. Properties with Only Getters
c"=*0"19)&190*A,2)*, read only propertyD*A&)(*,*'9))9%*C=)*2"*09))9%.*G>*)(9*:,7=9*">*)(9
#%"#9%)$*29:9%*B(,2'90*,>)9%*)(9*"CI9B)*(,0*C992*B"20)%=B)9;D*=09*, val >&97;R
class Message {
val timeStamp = new java.util.Date
...
}
-"19)&190D*("A9:9%D*$"=*A,2)*,*#%"#9%)$*)(,)*,*B7&92)*B,2L)*09)*,)*A&77D*C=)*)(,)*&0*1=),)9;
0"19*")(9%*A,$.*<(9 Counter B7,00*>%"1 -9B)&"2*5 &0*,*'"";*9H,1#79.*!"2B9#)=,77$D*)(9
B"=2)9%*(,0*, current #%"#9%)$*)(,)*&0*=#;,)9;*A(92*)(9 increment 19)(";*&0*B,779;D*C=)
)(9%9*&0*2"*09))9%*>"%*)(9*#%"#9%)$.
class Counter {
private var value: Int = 0
def increment() { value += 1 }
def current = value // f" () &2*;9B7,%,)&"2
}
<"*0=11,%&p9D*$"=*(,:9*>"=%*B("&B90*>"%*&1#79192)&2'*#%"#9%)&90R
5. var fooR*-B,7,*0$2)(90&p90*,*'9))9%*,2;*09))9%
3. val fooR*-B,7,*0$2)(90&p90*,*'9))9%
X. c"=*;9>&29*19)(";0 foo ,2; foo_=
Z. c"=*;9>&29*,*19)("; foo
Tip: b(92*$"=*099*,*>&97;*&2*,*-B,7,*B7,00D*%9191C9%*)(,)*&)*&0*2")*)(9*0,19*,0
,*>&97;*&2*?,:,*"%*!@@.*G)*&0*,*#%&:,)9*>&97; together with ,*'9))9%*M>"%*, val
>&97;N*"%*,*'9))9%*,2;*09))9%*M>"%*, var >&97;N.
[4
5.4. Object-Private Fields
G2*-B,7,*M,0*A977*,0*&2*?,:,*"%*!@@ND*,*19)(";*B,2*,BB900*)(9*#%&:,)9*>&97;0*"> all "CI9B)0
">*&)0*B7,00.*Y"%*9H,1#79D
class Person {
private var name
def comesBefore(otherPerson : Person) = name < otherPerson.
otherPerson.name
...
}
b&)(*,*B7,00J#%&:,)9*>&97;D*-B,7,*'929%,)90*#%&:,)9*'9))9%*,2;*09))9%*19)(";0.*/"A9:9%D*>"%
,2*"CI9B)J#%&:,)9*>&97;D*2"*'9))9%0*,2;*09))9%0*,%9*'929%,)9;*,)*,77.
Note: -B,7,*,77"A0*$"=*)"*'%,2)*,BB900*%&'()0*)"*0#9B&>&B*B7,0090.*<(9
private[ClassName] K=,7&>&9%*0),)90*)(,)*"27$*19)(";0*">*)(9*'&:92*B7,00*B,2
,BB900*)(9*'&:92*>&97;.*/9%9D*)(9 ClassName 1=0)*C9*)(9*2,19*">*)(9*B7,00*)(,)
&0*C9&2'*;9>&29;D*"%*,2*92B7"0&2'*B7,00.*M-99 )(9*nG229%*!7,0090*,2;*6C0)%,B)
<$#90o*B(,#)9% >"%*,*;&0B=00&"2*">*&229%*B7,0090.N
G2*)(&0*B,09D*)(9*&1#79192),)&"2*A&77*'929%,)9*,=H&7,%$*'9))9%*,2;*09))9%
19)(";0*)(,)*,77"A*)(9*92B7"0&2'*B7,00*)"*,BB900*)(9*>&97;.*<(909*19)(";0*,%9
#=C7&B*C9B,=09*)(9*?sP*;"90*2")*(,:9*,*>&29J'%,&29;*,BB900JB"2)%"7*0$0)91D
,2;*)(9$*(,:9*,2*&1#79192),)&"2J;9#92;92)*2,19.
[5
M"%*I=0)*, getFoo 19)(";*>"%*,*%9,;J"27$*#%"#9%)$N.*P,2$*?,:,*)""70*%97$*"2*)(&0*2,1&2'
B"2:92)&"2.
b(92*$"=*,22"),)9*,*-B,7,*>&97;*A&)( @reflect.BeanPropertyD*)(92*)(909*19)(";0*,%9
,=)"1,)&B,77$*'929%,)9;.*Y"%*9H,1#79D
class Person {
@BeanProperty var name : String = _
}
5. name : String
3. name_=(newValue : String) : Unit
X. getName() : String
Z. setName(newValue : String) : Unit
<,C79*5 0("A0*A(&B(*19)(";0*,%9*'929%,)9;*&2*,77*B,090.
<,C79*[J5R t929%,)9;*P9)(";0*>"%*Y&97;0
Generated
Scala Field When to Use
Methods
val name #=C7&B name <"*&1#79192)*,*#%"#9%)$*)(,)*&0
#=C7&B nameD #=C7&B7$*,BB900&C79*,2;*C,BE9;*C$*,
var name
name_= >&97;.
private[this] val/
<"*B"2>&29*)(9*>&97;*)"*19)(";0
var name
f"29 &2:"E9;*"2*)(9*0,19*"CI9B). f")
B"11"27$*=09;.
private[ClassName] G1#79192),)&"2J <"*'%,2)*,BB900*)"*,2*92B7"0&2'*B7,00.
val/var name ;9#92;92) f")*B"11"27$*=09;.
[3
Note: G>*$"=*;9>&29*,*>&97;*,0*,*#%&1,%$*B"20)%=B)"%*#,%,19)9%*M099 -9B)&"2*]ND
,2;*$"=*A,2)*?,:,V9,20*'9))9%0*,2;*09))9%0D*,22"),)9*)(9*B"20)%=B)"%
#,%,19)9%D*7&E9*)(&0R
b9*;&0B=00*,=H&7&,%$*B"20)%=B)"%0*>&%0)*C9B,=09*)(9$*,%9*9,0&9%*)"*=2;9%0),2;.*<(9$*,%9
:9%$*0&1&7,%*)"*B"20)%=B)"%0*&2*?,:,*"%*!@@D*A&)(*I=0)*)A"*;&>>9%92B90R
5. <(9*,=H&7&,%$*B"20)%=B)"%0*,%9*B,779; this.*MG2*?,:,*"%*!@@D*B"20)%=B)"%0*(,:9*)(9
0,19*2,19*,0*)(9*B7,00hA(&B(*&0*2")*0"*B"2:92&92)*&>*$"=*%92,19*)(9*B7,00.N
3. W,B(*,=H&7&,%$*B"20)%=B)"% must 0),%)*A&)(*,*B,77*)"*,*#%9:&"=07$*;9>&29;*,=H&7&,%$
B"20)%=B)"%*"%*)(9*#%&1,%$*B"20)%=B)"%.
/9%9*&0*,*B7,00*A&)(*)A"*,=H&7&,%$*B"20)%=B)"%0.
class Person {
private var name : String = ""
private var age : Int = 0
b9*A&77*7""E*,)*)(9*#%&1,%$*B"20)%=B)"%*&2*)(9*29H)*09B)&"2.*Y"%*2"AD*&)*&0*0=>>&B&92)*)"
E2"A*)(,)*,*B7,00*>"%*A(&B(*$"=*;"2L)*;9>&29*,*#%&1,%$*B"20)%=B)"%*(,0*,*#%&1,%$
B"20)%=B)"%*A&)(*2"*,%'=192)0.
c"=*B,2*B"20)%=B)*"CI9B)0*">*)(&0*B7,00*&2*)(%99*A,$0R
[X
val p1 = new Person // S%&1,%$*B"20)%=B)"%
val p2 = new Person("Fred") // Y&%0)*,=H&7&,%$*B"20)%=B)"%
val p3 = new Person("Fred", 42) // -9B"2;*,=H&7&,%$*B"20)%=B)"%
class Person(val
(val name: String, val age: Int) {
// S,%,19)9%0*">*#%&1,%$*B"20)%=B)"%*&2 (...)
...
}
S,%,19)9%0*">*)(9*#%&1,%$*B"20)%=B)"%*)=%2*&2)"*>&97;0*)(,)*,%9*&2&)&,7&p9;*A&)(*)(9
B"20)%=B)&"2*#,%,19)9%0.*G2*"=%*9H,1#79D name ,2; age C9B"19*>&97;0*">*)(9
Person B7,00.*6*B"20)%=B)"%*B,77*0=B(*,0 new Person("Fred", 42) 09)0*)(9 name
,2; age >&97;0.
/,7>*,*7&29*">*-B,7,*&0*)(9*9K=&:,792)*">*09:92*7&290*">*?,:,R
[Z
)(9 println 0),)9192)*&0*,*#,%)*">*)(9*#%&1,%$*B"20)%=B)"%.*G)*&0*9H9B=)9;
A(929:9%*,2*"CI9B)*&0*B"20)%=B)9;.
<(&0*&0*=09>=7*A(92*$"=*299;*)"*B"2>&'=%9*,*>&97;*;=%&2'*B"20)%=B)&"2.*Y"%
9H,1#79D
Note: G>*)(9%9*,%9*2"*#,%,19)9%0*,>)9%*)(9*B7,00*2,19D*)(92*)(9*B7,00*(,0*,
#%&1,%$*B"20)%=B)"%*A&)(*2"*#,%,19)9%0.*<(,)*B"20)%=B)"%*0&1#7$*9H9B=)90*,77
0),)9192)0*&2*)(9*C";$*">*)(9*B7,00.
S%&1,%$*B"20)%=B)"%*#,%,19)9%0*B,2*(,:9*,2$*">*)(9*>"%10*&2 <,C79*5.*Y"%*9H,1#79D
class Person(val
val name: String, private var age: Int)
;9B7,%90*,2;*&2&)&,7&p90*>&97;0
d Q)(9%A&09D*)(9*#,%,19)9%*&0*2")*0,:9;*,0*,*>&97;.*G)L0*I=0)*,*%9'=7,%*#,%,19)9%*)(,)
B,2*C9*,BB9009;*&2*)(9*B";9*">*)(9*#%&1,%$*B"20)%=B)"%.*M-)%&B)7$*0#9,E&2'D*)(&0*&0
,2*&1#79192),)&"2J0#9B&>&B*"#)&1&p,)&"2.N
[[
<,C79*3 0=11,%&p90*)(9*>&97;0*,2;*19)(";0*)(,)*,%9*'929%,)9;*>"%*;&>>9%92)*E&2;0*">
#%&1,%$*B"20)%=B)"%*#,%,19)9%0.
<,C79*[J3R Y&97;0*,2;*P9)(";0*t929%,)9;*Y"%*S%&1,%$*!"20)%=B)"%
S,%,19)9%0
Primary Constructor
Generated Field/Methods
Parameter
name: String
"CI9B)J#%&:,)9*>&97;D*"%*2"*>&97;*&>*2"*19)(";
=090 name
private valivarname: String #%&:,)9*>&97;D*#%&:,)9*'9))9%i09))9%
valivar name: String #%&:,)9*>&97;D*#=C7&B*'9))9%i09))9%
@BeanProperty valivarname: #%&:,)9*>&97;D*#=C7&B*-B,7,*,2;*?,:,V9,20
String '9))9%0i09))9%0
G>*$"=*>&2;*)(9*#%&1,%$*B"20)%=B)"%*2"),)&"2*B"2>=0&2'D*$"=*;"2L)*299;*)"*=09*&).*?=0)
#%":&;9*"29*"%*1"%9*,=H&7&,%$*B"20)%=B)"%0*&2*)(9*=0=,7*A,$D*C=)*%9191C9%*)"*B,77
this() &>*$"=*;"2L)*B(,&2*)"*,2")(9%*,=H&7&,%$*B"20)%=B)"%.
/"A9:9%D*1,2$*#%"'%,119%0*7&E9*)(9*B"2B&09*0$2),H.*P,%)&2*Q;9%0E$*0=''90)0*)"*)(&2E
,C"=)*&)*)(&0*A,$R*G2*-B,7,D*B7,0090*),E9*#,%,19)9%0D*I=0)*7&E9*19)(";0*;".
Note: b(92*$"=*)(&2E*">*#%&1,%$*B"20)%=B)"%*#,%,19)9%0*,0*B7,00*#,%,19)9%0D
#,%,19)9%0*A&)("=) val "% var C9B"19*9,0&9%*)"*=2;9%0),2;.*<(9*0B"#9*">*0=B(
,*#,%,19)9%*&0*)(9*92)&%9*B7,00.*<(9%9>"%9D*$"=*B,2 =09*)(9*#,%,19)9%*&2
19)(";0. G>*$"=*;"D*&)*&0*)(9*B"1#&79%L0*I"C*)"*0,:9*&)*&2*,*>&97;.
),E9*)(9*;9>&2&)&"2*,#,%)*&2)"*,*B7,00*;9>&2&)&"2
[\
class Person(
val name: String) {
var age: Int = 0
override def toString = "[name=" + name + ",age=" + age + "]"
}
,2;*,*B"20)%=B)"%*;9>&2&)&"2
6*B7,00*=09%*1=0)*)(92*=09*,2*,=H&7&,%$*B"20)%=B)"%*)"*B"20)%=B)*,
Person "CI9B).
import collection.mutable._
class Network {
class Member(val name: String) {
val contacts = new ArrayBuffer[Member]
}
[]
!"20&;9%*)A"*29)A"%E0R
Note: <(&0*&0*;&>>9%92)*)(,2*&2*?,:,D*A(9%9*,2*&229%*B7,00*C97"2'0*)"*)(9*"=)9%
B7,00.
<(9*-B,7,*,##%",B(*&0*1"%9*%9'=7,%.*Y"%*9H,1#79D*)"*1,E9*,*29A*&229%*"CI9B)D
$"=*0&1#7$*=09 new A&)(*)(9*)$#9*2,19R new chatter.Member.*G2*?,:,D*$"=
299;*)"*=09*,*0#9B&,7*0$2),HD chatter.new Member().
G2*"=%*29)A"%E*9H,1#79D*$"=*B,2*,;;*,*191C9%*A&)(&2*&)0*"A2*29)A"%ED*C=)*2")*,B%"00
29)A"%E0.
Y"%*29)A"%E0*">*#9"#79D*)(&0*C9(,:&"%*#%"C,C7$*1,E90*09209.*G>*$"=*;"2L)*A,2)*&)D*)(9%9
,%9*)A"*0"7=)&"20.
object Network {
class Member(val name: String) {
val contacts = new ArrayBuffer[Member]
}
}
class Network {
private val members = new ArrayBuffer[Network.Member]
...
}
[^
67)9%2,)&:97$D*$"=*B,2*=09*, type projection Network#MemberD*A(&B(*19,20*n, Member ">
any Networko.*Y"%*9H,1#79D
class Network {
class Member(val name: String) {
val contacts = new ArrayBuffer[Network#Member]
}
...
}
c"=*A"=7;*;"*)(,)*&>*$"=*A,2)*)(9*>&29J'%,&29;*n&229%*B7,00*#9%*"CI9B)o*>9,)=%9*&2*0"19
#7,B90*">*$"=%*#%"'%,1D*C=)*2")*9:9%$A(9%9.*-99 )(9*n6;:,2B9;*<$#90o*B(,#)9% >"%*1"%9
&2>"%1,)&"2*,C"=)*)$#9*#%"I9B)&"20.
class Outer {
outer =>
class Inner {
override def toString = super.toString + " inside " + outer
}
}
<(&0*0$2),H*&0*%97,)9;*)"*)(9*n097>*)$#9o*0$2),H*)(,)*$"=*A&77*099*&2 )(9
n6;:,2B9;*<$#90o*B(,#)9%.
5.9. Exercises
5. G1#%":9*)(9 Counter B7,00*&2 -9B)&"2*5 0"*)(,)*&)*;"902L)*)=%2*29',)&:9*,)
Int.MaxValue.
3. b%&)9*,*B7,00 BankAccount A&)(*19)(";0 deposit ,2; withdrawD*,2;*,*%9,;J"27$
#%"#9%)$ balance.
X. b%&)9*,*B7,00 Time A&)(*%9,;J"27$*#%"#9%)&90 hours ,2; minutes ,2;*,*19)(";
before(other: Time): Boolean )(,)*B(9BE0*A(9)(9%*)(&0*)&19*B"190*C9>"%9*)(9
")(9%.*6 Time "CI9B)*0("=7;*C9*B"20)%=B)9;*,0 new Time(hrs, min)D*A(9%9 hrs &0
&2*1&7&),%$*)&19*MC9)A992*4*,2;*3XN.
[_
Z. 89&1#79192)*)(9 Time B7,00*>%"1*)(9*#%9B9;&2'*9H9%B&09*0"*)(,)*)(9*&2)9%2,7
%9#%9092),)&"2*&0*)(9*2=1C9%*">*1&2=)90*0&2B9*1&;2&'()*MC9)A992*4*,2;*3Zu\4J5N.
Do not B(,2'9*)(9*#=C7&B*&2)9%>,B9.*<(,)*&0D*B7&92)*B";9*0("=7;*C9*=2,>>9B)9;*C$
$"=%*B(,2'9.
[. P,E9*,*B7,00 Student A&)(*%9,;JA%&)9*?,:,V9,20*#%"#9%)&90 name M">*)$#9 StringN
,2; id M">*)$#9 LongN.*b(,)*19)(";0*,%9*'929%,)9;g*Me09 javap )"*B(9BE.N*!,2
$"=*B,77*)(9*?,:,V9,20*'9))9%0*,2;*09))9%0*&2*-B,7,g*-("=7;*$"=g
\. G2*)(9 Person B7,00*"> -9B)&"2*5D*#%":&;9*,*#%&1,%$*B"20)%=B)"%*)(,)*)=%20*29',)&:9
,'90*)"*4.
]. b%&)9*,*B7,00 Person A&)(*,*#%&1,%$*B"20)%=B)"%*)(,)*,BB9#)0*,*0)%&2'*B"2),&2&2'*,
>&%0)*2,19D*,*0#,B9D*,2;*,*7,0)*2,19D*0=B(*,0 new Person("Fred Smith").*-=##7$
%9,;J"27$*#%"#9%)&90 firstName ,2; lastName.*-("=7;*)(9*#%&1,%$*B"20)%=B)"%
#,%,19)9%*C9*, varD*, valD*"%*,*#7,&2*#,%,19)9%g*b($g
^. P,E9*,*B7,00 Car A&)(*%9,;J"27$*#%"#9%)&90*>"%*1,2=>,B)=%9%D*1";97*2,19D*,2;
1";97*$9,%D*,2;*,*%9,;JA%&)9*#%"#9%)$*>"%*)(9*7&B9209*#7,)9.*-=##7$*>"=%
B"20)%=B)"%0.*677*%9K=&%9*)(9*1,2=>,B)=%9%*,2;*1";97*2,19.*Q#)&"2,77$D*1";97
$9,%*,2;*7&B9209*#7,)9*B,2*,70"*C9*0#9B&>&9;*&2*)(9*B"20)%=B)"%.*G>*2")D*)(9*1";97
$9,%*&0*09)*)"*J5*,2;*)(9*7&B9209*#7,)9*)"*)(9*91#)$*0)%&2'.*b(&B(*B"20)%=B)"%*,%9
$"=*B(""0&2'*,0*)(9*#%&1,%$*B"20)%=B)"%g*b($g
_. 89&1#79192)*)(9*B7,00*">*)(9*#%9B9;&2'*9H9%B&09*&2*?,:,D*!OD*"%*!@@*M$"=%
B("&B9N.*/"A*1=B(*0("%)9%*&0*)(9*-B,7,*B7,00g
54. !"20&;9%*)(9*B7,00
89A%&)9*&)*)"*=09*9H#7&B&)*>&97;0*,2;*,*;9>,=7)*#%&1,%$*B"20)%=B)"%.*b(&B(*>"%1*;"
$"=*#%9>9%g*b($g
\4
6. Objects (A1)
G2*)(&0*0("%)*B(,#)9%D*$"=*A&77*79,%2*A(92*)"*=09*)(9 object B"20)%=B)*&2*-B,7,.*c"=*=09*&)
A(929:9%*$"=*A,2)*,*B7,00*A&)(*,*0&2'79*&20),2B9D*"%*A(92*$"=*A,2)*)"*>&2;*,*("19*>"%
1&0B977,29"=0*:,7=90*"%*>=2B)&"20.
<(9*E9$*#"&2)0*">*)(&0*B(,#)9%*,%9R
d e09*"CI9B)0*>"%*0&2'79)"20*,2;*=)&7&)$*19)(";0
d 6*B7,00*B,2*(,:9*,*B"1#,2&"2*"CI9B)*A&)(*)(9*0,19*2,19
d QCI9B)0*B,2*9H)92;*B7,0090*"%*)%,&)0
d <(9 apply 19)(";*">*,2*"CI9B)*&0*=0=,77$*=09;*>"%*B"20)%=B)&2'*29A*&20),2B90*">
)(9*B"1#,2&"2*B7,00
d <"*,:"&;*)(9 main 19)(";D*=09*,2*"CI9B)*)(,)*9H)92;0*)(9 App )%,&)
d c"=*B,2*&1#79192)*92=19%,)&"20*C$*9H)92;&2'*)(9 Enumeration "CI9B)
6.1. Singletons
-B,7,*(,0*2"*0),)&B*19)(";0*"%*>&97;0.*G20)9,;D*$"=*=09*)(9 object B"20)%=B).*62*"CI9B)
;9>&290*,*0&2'79*&20),2B9*">*,*B7,00*A&)(*)(9*>9,)=%90*)(,)*$"=*;9>&29.*Y"%*9H,1#79D
object Accounts {
private var lastNumber = 0
def newUniqueNumber() { lastNumber += 1; lastNumber }
}
G>*$"=*299; ,*29A*=2&K=9*,BB"=2)*2=1C9%*&2*$"=%*,##7&B,)&"2D*$"=*B,77
Accounts.newUniqueNumber().
<(9*B"20)%=B)"%*">*,2*"CI9B)*&0*9H9B=)9;*A(92*)(9*"CI9B)*&0*>&%0)*=09;.*G2*"=%*9H,1#79D*)(9
Accounts B"20)%=B)"%*&0*9H9B=)9;*A&)(*)(9*>&%0)*B,77*)" Accounts.newUniqueNumber().*G>*,2
"CI9B)*&0*29:9%*=09;D*&)0*B"20)%=B)"%*&0*2")*9H9B=)9;.
62*"CI9B)*B,2*(,:9*90092)&,77$*,77*)(9*>9,)=%90*">*,*B7,00h&)*B,2*9:92*9H)92;*")(9%*B7,0090
"%*)%,&)0*M099 -9B)&"2*XN.*<(9%9*&0*I=0)*"29*9HB9#)&"2.*c"=*B,22")*#%":&;9*B"20)%=B)"%
#,%,19)9%0.
c"=*=09*,2*"CI9B)*&2*-B,7,*A(929:9%*$"=*A"=7;*(,:9*=09;*,*0&2'79)"2*"CI9B)*&2*?,:,*"%
!@@R
d ,0*,*("19*>"%*=)&7&)$*>=2B)&"20*"%*B"20),2)0
d A(92*,*0&2'79*&11=),C79*&20),2B9*B,2*C9*0(,%9;*9>>&B&92)7$
\5
d A(92*,*0&2'79*&20),2B9*&0*%9K=&%9;*)"*B""%;&2,)9*0"19*09%:&B9*M&.9.D*)(9*-&2'79)"2
;90&'2*#,))9%2N
Note: P,2$*#9"#79*:&9A*)(9*-&2'79)"2*;90&'2*#,))9%2*A&)(*;&0;,&2.*-B,7,
'&:90*$"=*)(9*)""70*>"%*C")(*'"";*,2;*C,;*;90&'2D*,2;*&)*&0*=#*)"*$"=*)"*=09
)(91*A&097$.
class Account {
val id = Account.newUniqueNumber()
private var balance = 0.0
public def deposit(amount: Double) { balance += amount }
...
}
<(9*B7,00*,2;*B"1#,2&"2*"CI9B)*B,2*,BB900*9,B(*")(9%L0*#%&:,)9*>9,)=%90.*<(9$*1=0)*C9
7"B,)9;*&2*)(9 same source file.
Tip: G2*)(9*8WSTD*$"=*1=0)*;9>&29*)(9*B7,00*,2;*"CI9B)*)"'9)(9%*&2*#,0)9
1";9.*<$#9
:paste
<(92*)$#9*"%*#,0)9*C")(*)(9*B7,00*,2;*"CI9B)*;9>&2&)&"2D*,2;*)$#9 !Qf<8QT@a.
\3
Q29*=09>=7*,##7&B,)&"2*&0*)"*0#9B&>$*;9>,=7)*"CI9B)0*)(,)*B,2*C9*0(,%9;.*Y"%*9H,1#79D
B"20&;9%*,*B7,00*>"%*=2;",C79*,B)&"20*&2*,*#%"'%,1.
6*=09>=7*;9>,=7)*&0*)(9*n;"*2")(&2'o*,B)&"2.*Q>*B"=%09D*A9*"27$*299;*"29*">*)(91.
\X
6.5. Application Objects
W,B(*-B,7,*#%"'%,1*1=0)*0),%)*A&)(*,2*"CI9B)L0 main 19)(";*">*)$#9 Array[String] =>
UnitR
object Hello {
def main(args: Array[String]) {
println("Hello, World!")
}
}
\Z
6.6. Enumerations
e27&E9*?,:,*"%*!@@D*-B,7,*;"90*2")*(,:9*92=19%,)9;*)$#90.*/"A9:9%D*)(9*0),2;,%;*7&C%,%$
#%":&;90*,2 Enumeration (97#9%*B7,00*)(,)*$"=*B,2*=09*)"*#%";=B9*92=19%,)&"20.
G>*2")*0#9B&>&9;D*)(9*GU*&0*"29*1"%9*)(,2*)(9*#%9:&"=07$*,00&'29;*"29D*0),%)&2'*A&)(*p9%".
<(9*;9>,=7)*2,19*&0*)(9*>&97;*2,19.
c"=*B,2*2"A*%9>9%*)"*)(9*92=19%,)&"2*:,7=90*,0 TrafficLightColor.RedD*,2;*0"*"2.*G>*)(,)
'9)0*)""*)9;&"=0D*=09*,*0),)9192)
import TrafficLightColor._
\[
val Red, Yellow, Green = Value
}
f"A*)(9*)$#9*">*)(9*92=19%,)&"2*&0 TrafficLightColor.TrafficLightColorD*A(&B(*&0
"27$*,2*&1#%":9192)*&>*$"=*=09*,2 import 0),)9192).*Y"%*9H,1#79D
import TrafficLightColor._
def doWhat(color: TrafficLightColor) =
if (color == Red) "stop"
else if (color == Yellow) "hurry up"
else if (color == Green) "go"
<(9*GU*">*,2*92=19%,)&"2*:,7=9*&0*%9)=%29;*C$*)(9 id 19)(";D*,2;*)(9*2,19*C$*)(9
toString 19)(";.
Y&2,77$D*$"=*B,2*7""E*=#*,2*92=19%,)&"2*:,7=9*C$*GU*"%*2,19.*V")(*">*)(9*>"77"A&2'
$&97;*)(9*"CI9B) TrafficLightColor.Red.
6.7. Exercises
5. b%&)9*,2*"CI9B) Conversions A&)(*19)(";0 inchesToCentimeterD gallonsToLiterD
,2; milesToKilometer.
3. <(9*#%9B9;&2'*#%"C791*A,02L)*:9%$*"CI9B)J"%&92)9;.*S%":&;9*,*'929%,7*0=#9%B7,00
UnitConversion ,2;*;9>&29*"CI9B)0 InchesToCentimeterD GallonsToLiterD*,2;
MilesToKilometer )(,)*9H)92;*&).
X. U9>&29*,2 Origin "CI9B)*)(,)*9H)92;0 java.awt.Point.*b($*&0*)(&0*2")*,B)=,77$*,
'"";*&;9,g*M/,:9*,*B7"09*7""E*,)*)(9*19)(";0*">*)(9 Point B7,00.N
Z. U9>&29*, Point B7,00*A&)(*,*B"1#,2&"2*"CI9B)*0"*)(,)*$"=*B,2*B"20)%=B) Point
&20),2B90*,0 Point(3, 4)D*A&)("=)*=0&2' new.
[. b%&)9*,*-B,7,*,##7&B,)&"2D*=0&2'*)(9 App )%,&)D*)(,)*#%&2)0*)(9*B"11,2;J7&29
,%'=192)0*&2*%9:9%09*"%;9%D*09#,%,)9;*C$*0#,B90.*Y"%*9H,1#79D scala Reverse
Hello World 0("=7;*#%&2) World Hello.
\. b%&)9*,2*92=19%,)&"2*;90B%&C&2'*)(9*>"=%*#7,$&2'*B,%;*0=&)0*0"*)(,)*)(9 toString
19)(";*%9)=%20*vD*wD*xD*y.
]. G1#79192)*,*>=2B)&"2*)(,)*B(9BE0*A(9)(9%*,*B,%;*0=&)*:,7=9*>%"1*)(9*#%9B9;&2'
9H9%B&09*&0*%9;.
\\
^. b%&)9*,2*92=19%,)&"2*;90B%&C&2'*)(9*9&'()*B"%29%0*">*)(9*8tV*B"7"%*B=C9.*60
GU0D*=09*)(9*B"7"%*:,7=90*M>"%*9H,1#79D 0xff0000 >"% RedN.
\]
7. Packages and Imports (A1)
G2*)(&0*B(,#)9%D*$"=*A&77*79,%2*("A*#,BE,'90*,2;*&1#"%)*0),)9192)0*A"%E*&2*-B,7,.*V")(
#,BE,'90*,2;*&1#"%)0*,%9*1"%9*%9'=7,%*)(,2*&2*?,:,D*,2;*)(9$*,%9*,70"*,*C&)*1"%9*>79H&C79.
<(9*E9$*#"&2)0*">*)(&0*B(,#)9%*,%9R
d S,BE,'90*290)*I=0)*7&E9*&229%*B7,0090
d S,BE,'9*#,)(0*,%9 not ,C0"7=)9
d 6*B(,&2 x.y.z &2*,*#,BE,'9*B7,=09*79,:90*)(9*&2)9%19;&,)9*#,BE,'90 x ,2; x.y
&2:&0&C79
d S,BE,'9*0),)9192)0*A&)("=)*C%,B90*,)*)(9*)"#*">*)(9*>&79*9H)92;*)"*)(9*92)&%9*>&79
d 6*#,BE,'9*"CI9B)*B,2*("7;*>=2B)&"20*,2;*:,%&,C790
d G1#"%)*0),)9192)0*B,2*&1#"%)*#,BE,'90D*B7,0090D*,2;*"CI9B)0
d G1#"%)*0),)9192)0*B,2*C9*,2$A(9%9
d G1#"%)*0),)9192)0*B,2*%92,19*,2;*(&;9*191C9%0
d java.langD scalaD*,2; Predef ,%9*,7A,$0*&1#"%)9;
7.1. Packages
S,BE,'90*&2*-B,7,*>=7>&77*)(9*0,19*#=%#"09*,0*#,BE,'90*&2*?,:,*"%*2,190#,B90*&2*!@@D*)"
1,2,'9*2,190*&2*,*7,%'9*#%"'%,1.*Y"%*9H,1#79D*)(9*2,19 Map B,2*"BB=%*&2*)(9*#,BE,'90
scala.collection.immutable ,2; scala.collection.mutable A&)("=)*B"2>7&B).*<"*,BB900
9&)(9%*2,19D*$"=*B,2*=09*)(9*>=77$*K=,7&>&9; scala.collection.immutable.Map "%
scala.collection.mutable.Map.*67)9%2,)&:97$D*=09*,2 import 0),)9192)*)"*#%":&;9*,
0("%)9%*,7&,0h099 -9B)&"2*].
<"*,;;*&)910*)"*,*#,BE,'9D*$"=*B,2*&2B7=;9*)(91*&2*#,BE,'9*0),)9192)0*0=B(*,0
package com {
package horstmann {
package impatient {
class Person
...
}
}
}
\^
e27&E9*)(9*;9>&2&)&"2*">*,2*"CI9B)*"%*,*B7,00D*,*#,BE,'9*B,2*C9*;9>&29;*":9%*1=7)O*>&790.
<(9*#%9B9;&2'*B";9*1&'()*C9*&2*,*>&79 Person.scalaD*,2;*,*>&79 Student.scala 1&'()
B"2),&2
package com {
package horstmann {
package impatient {
class Student extends Person
...
}
}
}
Note: <(9%9*&0*2"*92>"%B9;*%97,)&"20(&#*C9)A992*)(9*;&%9B)"%$*">*)(9*0"=%B9
>&79*,2;*)(9*#,BE,'9.*c"=*;"2L)*(,:9*)"*#=) Person.scala ,2; Student.scala
&2)"*, com/horstmann/impatient ;&%9B)"%$.
!"2:9%097$D*$"=*B,2*B"2)%&C=)9*)"*1"%9*)(,2*"29*#,BE,'9*&2*,*0&2'79*>&79.*<(9*>&79
Person.scala B,2*B"2),&2
package com {
package horstmann {
package impatient {
class Person
...
}
}
}
package org {
package bigjava {
class Student extends com.horstmann.impatient.Person
}
}
\_
package com {
package horstmann {
object Utils {
def percentOf(value: Double, rate: Double) = value * rate / 100
...
}
package impatient {
class Employee {
...
def giveRaise(rate: scala.Double) {
salary += Utils.percentOf
Utils.percentOf(salary, rate)
}
}
}
}
}
<(9%9*&0*,*>7$*&2*)(9*"&2)192)D*("A9:9%.*!"20&;9%
package com {
package horstmann {
package impatient {
class Manager {
val subordinates = new scala.collection.mutable.ArrayBuffer[Employee]
...
}
}
}
}
62;*2"A*0=##"09*0"19"29*&2)%";=B90*)(9*>"77"A&2'*#,BE,'9D*#9%(,#0*&2*,*;&>>9%92)*>&79.
package com {
package horstmann {
package scala {
...
}
}
]4
f"A*)(9 Manager B7,00*2"*7"2'9%*B"1#&790.*G)*7""E0*>"%*, collection 191C9%*&20&;9*)(9
impatient.scala #,BE,'9*,2;*;"902L)*>&2;*&).*<(9*&2)92)*&2*)(9 Manager B7,00*A,0*)(9*)"#J
79:97 scala #,BE,'9D*2")*A(,)9:9% scala 0=C#,BE,'9*(,##929;*)"*C9*&2*0"19*,BB900&C79
0B"#9D*C=)*)(,)L0*2")*("A*#,BE,'9*0B"#90*A"%E*&2*-B,7,.
G2*?,:,D*)(&0*#%"C791*B,2L)*"BB=%*C9B,=09*#,BE,'9*2,190*,%9*,7A,$0 absoluteD*0),%)&2'*,)
)(9*%"")*">*)(9*#,BE,'9*(&9%,%B($.*V=)*&2*-B,7,D*#,BE,'9*2,190*,%9*%97,)&:9D*I=0)*7&E9*&229%
B7,00*2,190.*b&)(*&229%*B7,0090D*"29*;"902L)*=0=,77$*%=2*&2)"*#%"C7910*C9B,=09*,77*)(9
B";9*&0*"29*>&79D*=2;9%*B"2)%"7*">*A("9:9%*&0*&2*B(,%'9*">*)(,)*>&79.*V=)*#,BE,'90*,%9*"#92J
92;9;.*62$"29*B,2*B"2)%&C=)9*)"*,*#,BE,'9*,)*,2$*)&19.
Q29*0"7=)&"2*&0*)"*=09*,C0"7=)9*#,BE,'9*2,190D*0),%)&2'*A&)( _root_D*>"%*9H,1#79
62")(9%*,##%",B(*&0*)"*=09*nB(,&29;o*#,BE,'9*B7,=090h099*)(9*29H)*09B)&"2.
package com.horstmann.impatient {
// P91C9%0*"> com ,2; com.horstmann ,%9 not :&0&C79*(9%9
package people {
class Person
...
}
}
package com.horstmann.impatient
package people
class Person
...
<(&0*&0*9K=&:,792)*)"
]5
package com.horstmann.impatient {
package people {
class Person
...
// e2)&7*)(9*92;*">*)(9*>&79
}
}
<(&0*&0*)(9*#%9>9%%9;*2"),)&"2*&>*,77*)(9*B";9*&2*)(9*>&79*C97"2'0*)"*)(9*0,19*#,BE,'9
MA(&B(*&0*)(9*=0=,7*B,09N.
f")9*)(,)*&2*)(9*9H,1#79*,C":9D*9:9%$)(&2'*&2*)(9*>&79*C97"2'0*)"*)(9*#,BE,'9
com.horstmann.impatient.peopleD*C=)*)(9*#,BE,'9 com.horstmann.impatient (,0*,70"
C992*"#929;*=#D*0"*)(,)*"29*B,2*%9>9%*)"*&)0*B"2)92)0.
package com.horstmann.impatient
package people {
class Person {
var name = defaultName // 6*B"20),2)*>%"1*)(9*#,BE,'9
}
...
}
V9(&2;*)(9*0B9290D*)(9*#,BE,'9*"CI9B)*'9)0*B"1#&79;*&2)"*,*?sP*B7,00*A&)(*0),)&B*19)(";0
,2;*>&97;0D*B,779; package.class &20&;9*)(9*#,BE,'9.*G2*"=%*9H,1#79D*)(,)*A"=7;*C9*,*B7,00
]3
com.horstmann.impatient.people.package A&)(*,*0),)&B*>&97; defaultName.*MG2*)(9*?sPD
$"=*B,2*=09 package ,0*,*B7,00*2,19.N
G)*&0*,*'"";*&;9,*)"*=09*)(9*0,19*2,1&2'*0B(919*>"%*0"=%B9*>&790.*S=)*)(9*#,BE,'9*"CI9B)
&2)"*,*>&79 com/horstmann/impatient/people/package.scala.*<(,)*A,$D*,2$"29*A("
A,2)0*)"*,;;*>=2B)&"20*"%*:,%&,C790*)"*,*#,BE,'9*B,2*>&2;*)(9*#,BE,'9*"CI9B)*9,0&7$.
package com.horstmann.impatient.people
class Person {
private[people] def giveRaise(rate: Double)
...
}
c"=*B,2*9H)92;*)(9*:&0&C&7&)$*)"*,2*92B7"0&2'*#,BE,'9R
7.7. Imports
G1#"%)0*79)*$"=*=09*0("%)*2,190*&20)9,;*">*7"2'*"290.*b&)(*)(9*B7,=09
import scala.collection.mutable.HashMap
<(,)*&0*)(9*0"79*#=%#"09*">*&1#"%)0.*G>*$"=*;"2L)*1&2;*7"2'*2,190D*$"=*29:9%*299;*)(91.
c"=*B,2*&1#"%)*,77*191C9%0*">*,*#,BE,'9*,0
import scala.collection.mutable._
c"=*B,2*,70"*&1#"%)*,77*191C9%0*">*,*B7,00*"%*"CI9B).
]X
import java.awt.Color._
val c1 = RED // Color.RED
val c2 = decode("#ff0000") // Color.decode
b(92*$"=*&1#"%)*,*#,BE,'9D*$"=*B,2*,BB900*&)0*0=C#,BE,'90*A&)(*0("%)9%*2,190.*Y"%
9H,1#79D
import java.awt._
class Manager {
import scala.collection.mutable._
val subordinates = new ArrayBuffer[Employee]
...
}
<(&0*&0*,*:9%$*=09>=7*>9,)=%9D*#,%)&B=7,%7$*A&)(*A&7;B,%;*&1#"%)0.*G)*&0*,7A,$0*,*C&)
A"%%&0"19*)"*&1#"%)*7")0*">*2,190*>%"1*;&>>9%92)*0"=%B90.*G2*>,B)D*0"19*?,:,
#%"'%,119%0*;&07&E9*A&7;B,%;*&1#"%)0*0"*1=B(*)(,)*)(9$*29:9%*=09*)(91D*C=)*79)*)(9*GUW
'929%,)9*7"2'*7&0)0*">*&1#"%)9;*B7,0090.
V$*#=))&2'*)(9*&1#"%)0*A(9%9*)(9$*,%9*299;9;D*$"=*B,2*'%9,)7$*%9;=B9*)(9*#")92)&,7*>"%
B"2>7&B)0.
<(9*0979B)"%*0$2),H*79)0*$"=*%92,19*191C9%0.
]Z
import java.util.{HashMap => JavaHashMap}
import scala.collection.mutable._
import java.lang._
import scala._
import Predef._
import collection.mutable.HashMap
&0*I=0)*,0*'"";*,0
import scala.collection.mutable.HashMap
7.11. Exercises
5. b%&)9*,2*9H,1#79*#%"'%,1*)"*;91"20)%,)9*)(,)
][
package com.horstmann.impatient
&0*2")*)(9*0,19*,0
package com
package horstmann
package impatient
import java._
import javax._
G0*)(&0*,*'"";*&;9,g
]\
8. Inheritance (A1)
G2*)(&0*B(,#)9%D*$"=*A&77*79,%2*)(9*1"0)*&1#"%),2)*A,$0*&2*A(&B(*&2(9%&),2B9*&2*-B,7,
;&>>9%0*>%"1*&)0*B"=2)9%#,%)*&2*?,:,*"%*!@@.*<(9*(&'(7&'()0*,%9R
G2*)(&0*B(,#)9%D*A9*"27$*;&0B=00*)(9*B,09*&2*A(&B(*,*B7,00*&2(9%&)0*>%"1*,2")(9%*B7,00.*-99
)(9*n<%,&)0o*B(,#)9% >"%*&2(9%&)&2' traitsh)(9*-B,7,*B"2B9#)*)(,)*'929%,7&p90*?,:,
&2)9%>,B90.
60*&2*?,:,D*$"=*0#9B&>$*>&97;0*,2;*19)(";0*)(,)*,%9*29A*)"*)(9*0=CB7,00*"%*)(,)*":9%%&;9
19)(";0*&2*)(9*0=#9%B7,00.
]]
d b(92*$"=*1&00#977*)(9*2,19*">*)(9*19)(";*)(,)*$"=*,%9*":9%%&;&2'
d b(92*$"=*,BB&;92),77$*#%":&;9*)(9*A%"2'*#,%,19)9%*)$#9*&2*)(9*":9%%&;&2'
19)(";
d b(92*$"=*&2)%";=B9*,*29A*19)(";*&2*,*0=#9%B7,00*)(,)*B7,0(90*A&)(*,*0=CB7,00
19)(";
G2*?,:,D*"29*&0*">)92*,;:&09;*)"*n0"7:9o*)(&0*#%"C791*C$*;9B7,%&2'*,77*19)(";0
,0 final =27900*)(9$*,%9*9H#7&B&)7$*;90&'29;*)"*C9*":9%%&;;92.*<(,)*0"=2;0
'"";*&2*)(9"%$D*C=)*#%"'%,119%0*(,)9*&)*&>*)(9$*B,2L)*9:92*1,E9*)(9*1"0)
&22"B="=0*B(,2'90*)"*,*19)(";*M0=B(*,0*,;;&2'*,*7"''&2'*B,77N.*<(,)L0*A($
?,:,*9:92)=,77$*&2)%";=B9;*,2*"#)&"2,7 @Overrides ,22"),)&"2.
G2:"E&2'*,*0=#9%B7,00*19)(";*A"%E0*9H,B)7$*7&E9*&2*?,:,D*A&)(*)(9*E9$A"%; superR
if (p.isInstanceOf[Student]) {
val s = p.asInstanceOf[Student] // s (,0*)$#9 Student
...
}
]^
G> p &0 nullD*)(92 p.isInstanceOf[Student] %9)=%20 false ,2; p.asInstanceOf[Student]
%9)=%20 null.
if (p.getClass == classOf[Student])
<,C79*5 0("A0*)(9*B"%%%90#"2;92B9*C9)A992*-B,7,*,2;*?,:,*)$#9*B(9BE0*,2;*B,0)0.
<,C79*^J5R <$#9*!(9BE0*,2;*!,0)0*&2*-B,7,*,2;*?,:,
Scala Java
obj.isInstanceOf[Cl] obj instanceof Cl
obj.asInstanceOf[Cl] (Cl) obj "% null &> obj &0*2")*,2*&20),2B9*"> C
classOf[Cl] Cl.class
/"A9:9%D*#,))9%2*1,)B(&2'*&0*=0=,77$*,*C9))9%*,7)9%2,)&:9*)(,2*=0&2'*)$#9*B(9BE0*,2;
B,0)0.*Y"%*9H,1#79D
p match {
case s: Student => ... // S%"B900 s ,0*, Student
case _ => ... // p A,02L)*, Student
}
]_
8.5. Superclass Construction
89B,77*>%"1 )(9*n!7,0090o*B(,#)9% )(,)*,*B7,00*(,0*,2$*2=1C9%*">*,=H&7&,%$*B"20)%=B)"%0
,2;*"29*#%&1,%$*B"20)%=B)"%D*,2;*)(,)*,77*,=H&7&,%$*B"20)%=B)"%0*1=0)*0),%)*A&)(*,*B,77*)"*,
#%9B9;&2'*,=H&7&,%$*B"20)%=B)"%*"%*)(9*#%&1,%$*B"20)%=B)"%.
<(9*,=H&7&,%$*B"20)%=B)"%0*">*)(9*0=CB7,00*9:92)=,77$*B,77*)(9*#%&1,%$*B"20)%=B)"%*">*)(9
0=CB7,00.*Q27$*)(9*#%&1,%$*B"20)%=B)"%*B,2*B,77*,*0=#9%B7,00*B"20)%=B)"%.
89B,77*)(,)*)(9*#%&1,%$*B"20)%=B)"%*&0*&2)9%)A&29;*A&)(*)(9*B7,00*;9>&2&)&"2.*<(9*B,77*)"*)(9
0=#9%B7,00*B"20)%=B)"%*&0*0&1&7,%7$*&2)9%)A&29;.*/9%9*&0*,2*9H,1#79.
<(9*-B,7,*9K=&:,792)*&0R
<(&0*;9>&290*,*0=CB7,00
,2;*,*#%&1,%$*B"20)%=B)"%*)(,)*B,770*)(9*0=#9%B7,00*B"20)%=B)"%
G2)9%)A&2&2'*)(9*B7,00*,2;*)(9*B"20)%=B)"%*1,E90*>"%*:9%$*B"2B&09*B";9.*c"=*1,$*>&2;*&)
(97#>=7*)"*)(&2E*">*)(9*#%&1,%$*B"20)%=B)"%*#,%,19)9%0*,0*#,%,19)9%0*">*)(9*B7,00.*/9%9D
)(9 Employee B7,00*(,0*)(%99*#,%,19)9%0 nameD ageD*,2; salaryD*)A"*">*A(&B(*&)*n#,0090o*)"
)(9*0=#9%B7,00.
G2*?,:,D*)(9*9K=&:,792)*B";9*&0*K=&)9*,*C&)*1"%9*:9%C"09.
^4
Note: G2*,*-B,7,*B"20)%=B)"%D*$"=*B,2*29:9%*B,77 super(params)D*,0*$"=*A"=7;
&2*?,:,D*)"*B,77*)(9*0=#9%B7,00*B"20)%=B)"%.
6*-B,7,*B7,00*B,2*9H)92;*,*?,:,*B7,00.*G)0*#%&1,%$*B"20)%=B)"%*1=0)*&2:"E9*"29*">*)(9
B"20)%=B)"%0*">*)(9*?,:,*0=#9%B7,00.*Y"%*9H,1#79D
Y"%*9H,1#79D
<(&0*9H,1#79*0("A0*)(9*19B(,2&B0D*C=)*&)*&0*%,)(9%*,%)&>&B&,7.*6*1"%9*B"11"2*B,09*&0*)"
":9%%&;9*,2*,C0)%,B) def A&)(*, valD*7&E9*)(&0R
class Student(override
override val id: Int) extends Person
// 6*0)=;92)*GU*&0*0&1#7$*#%":&;9;*&2*)(9*B"20)%=B)"%
f")9*)(9*>"77"A&2'*%90)%&B)&"20*M099*,70" <,C79*3NR
^5
d 6 var B,2*"27$*":9%%&;9*,2*,C0)%,B) var M099 -9B)&"2*^N
^3
8.8. Abstract Classes
60*&2*?,:,D*$"=*=09*)(9 abstract E9$A"%;*)"*;92")9*,*B7,00*)(,)*B,22")*C9*&20),2)&,)9;D
=0=,77$*C9B,=09*"29*"%*1"%9*">*&)0*19)(";0*&0*2")*;9>&29;.*Y"%*9H,1#79D
/9%9*A9*0,$*)(,)*9:9%$*#9%0"2*(,0*,2*GUD*C=)*A9*;"2L)*E2"A*("A*)"*B"1#=)9*&).*W,B(
B"2B%9)9*0=CB7,00*"> Person 299;0*)"*0#9B&>$*,2 id 19)(";.*G2*-B,7,D*=27&E9*?,:,D*$"=*;"
2")*=09*)(9 abstract E9$A"%;*>"%*,2*,C0)%,B)*19)(";.*c"=*0&1#7$*"1&)*&)0*C";$.*60*&2
?,:,D*,*B7,00*A&)(*,)*79,0)*"29*,C0)%,B)*19)(";*1=0)*C9*;9B7,%9; abstract.
!"2B%9)9*0=CB7,0090*1=0)*#%":&;9*B"2B%9)9*>&97;0D*>"%*9H,1#79R
c"=*B,2*,7A,$0*B=0)"1&p9*,2*,C0)%,B)*>&97;*C$*=0&2'*,2*,2"2$1"=0*)$#9R
^X
val fred = new Person {
val id = 1729
var name = "Fred"
}
/9%9*&0*,2*9H,1#79.*6*B%9,)=%9*B,2*09209*,*#,%)*">*&)0*92:&%"2192).*Y"%*0&1#7&B&)$D*A9
,00=19*)(9*B%9,)=%9*7&:90*&2*,*"29J;&1920&"2,7*A"%7;D*,2;*)(9*0920"%$*;,),*,%9
%9#%9092)9;*,0*&2)9'9%0.*6*;9>,=7)*B%9,)=%9*B,2*099*)92*=2&)0*,(9,;.
class Creature {
val range: Int = 10
val env: Array[Int] = new Array[Int](range)
}
62)0D*("A9:9%D*,%9*29,%J0&'()9;R
^Z
G2*?,:,D*$"=*(,:9*,*0&1&7,%*&00=9*A(92*$"=*B,77*,*19)(";*&2*,*0=#9%B7,00*B"20)%=B)"%.*<(9
19)(";*1&'()*C9*":9%%&;;92*&2*,*0=CB7,00D*,2;*&)*1&'()*2")*;"*A(,)*$"=*A,2)*&)*)"*;".*MG2
>,B)D*)(,)*&0*)(9*%"")*B,=09*">*"=%*#%"C791h)(9*9H#%900&"2 range B,770*)(9*'9))9%*19)(";.N
<(9%9*,%9*09:9%,7*%919;&90R
<(9*%&'()*(,2;*0&;9*">*,2*9,%7$*;9>&2&)&"2*B,2*"27$*%9>9%*)"*#%9:&"=0*9,%7$*;9>&2&)&"20D*2")
)"*")(9%*>&97;0*"%*19)(";0*">*)(9*B7,00.
Note: 6)*)(9*%"")*">*)(9*B"20)%=B)&"2*"%;9%*#%"C791*7&90*,*;90&'2*;9B&0&"2*">
)(9*?,:,*7,2'=,'9D*2,197$*)"*,77"A*)(9*&2:"B,)&"2*">*0=CB7,00*19)(";0*&2*,
0=#9%B7,00*B"20)%=B)"%.*G2*!@@D*,2*"CI9B)L0*:&%)=,7*>=2B)&"2*),C79*#"&2)9%*&0*09)
)"*)(9*),C79*">*)(9*0=#9%B7,00*A(92*)(9*0=#9%B7,00*B"20)%=B)"%*9H9B=)90.
6>)9%A,%;0D*)(9*#"&2)9%*&0*09)*)"*)(9*0=CB7,00*),C79.*<(9%9>"%9D*&2*!@@D*&)*&0*2")
#"00&C79*)"*1";&>$*B"20)%=B)"%*C9(,:&"%*)(%"='(*":9%%&;&2'.*<(9*?,:,
;90&'29%0*>97)*)(,)*)(&0*0=C)79)$*A,0*=229B900,%$D*,2;*)(9*?,:,*:&%)=,7*1,B(&29
;"90*2")*,;I=0)*)(9*:&%)=,7*>=2B)&"2*),C79*;=%&2'*B"20)%=B)&"2.
^[
677*")(9%*B7,0090*,%9*0=CB7,0090*">*)(9 AnyRef B7,00D*A(&B(*&0*,*0$2"2$1*>"%*)(9 Object
B7,00*>%"1*)(9*?,:,*"%*.fW<*:&%)=,7*1,B(&29.
AnyVal ;"90*2")*,;;*,2$*19)(";0.*G)*&0*I=0)*,*1,%E9%*>"%*:,7=9*)$#90.
^\
Note: ?=0)*7&E9*&2*?,:,D*G*0=''90)*$"=*0),$*,A,$*>%"1 waitD notifyD*,2;
synchronized =27900*$"=*(,:9*,*'"";*%9,0"2*)"*=09*)(91*&20)9,;*">*(&'(9%J
79:97*B"2B=%%92B$*B"20)%=B)0.
677*-B,7,*B7,0090*&1#79192)*)(9*1,%E9%*&2)9%>,B9 ScalaObjectD*A(&B(*(,0*2"*19)(";0.
^]
else description == that.description && price == that.price
}
8.13. Exercises
5. WH)92;*)(9*>"77"A&2' BankAccount B7,00*)"*, CheckingAccount B7,00*)(,)*B(,%'90
|5*>"%*9:9%$*;9#"0&)*,2;*A&)(;%,A,7.
^^
,2;*)(,)*(,0*)(%99*>%99*;9#"0&)0*"%*A&)(;%,A,70*9:9%$*1"2)(.*8909)*)(9
)%,20,B)&"2*B"=2)*&2*)(9 earnMonthlyInterest 19)(";.
X. !"20=7)*$"=%*>,:"%&)9*?,:,*"%*!@@*)9H)C""E*)(,)*&0*0=%9*)"*(,:9*,2*9H,1#79*">*,
)"$*&2(9%&),2B9*(&9%,%B($D*#9%(,#0*&2:"7:&2'*91#7"$990D*#9)0D*'%,#(&B,7*0(,#90D
"%*)(9*7&E9.*G1#79192)*)(9*9H,1#79*&2*-B,7,.
Z. U9>&29*,2*,C0)%,B)*B7,00 Item A&)(*19)(";0 price ,2; description.*6 SimpleItem
&0*,2*&)91*A("09*#%&B9*,2;*;90B%&#)&"2*,%9*0#9B&>&9;*&2*)(9*B"20)%=B)"%.*<,E9
,;:,2),'9*">*)(9*>,B)*)(,)*, val B,2*":9%%&;9*, def.*6 Bundle &0*,2*&)91*)(,)
B"2),&20*")(9%*&)910.*G)0*#%&B9*&0*)(9*0=1*">*)(9*#%&B90*&2*)(9*C=2;79.*670"*#%":&;9
,*19B(,2&01*>"%*,;;&2'*&)910*)"*)(9*C=2;79*,2;*,*0=&),C79 description 19)(";.
[. U90&'2*,*B7,00 Point A("09 xJ*,2; yJB""%;&2,)9*:,7=90*B,2*C9*#%":&;9;*&2*,
B"20)%=B)"%.*S%":&;9*,*0=CB7,00 LabeledPoint A("09*B"20)%=B)"%*),E90*,*7,C97
:,7=9*,2; xJ*,2; yJB""%;&2,)90D*0=B(*,0
^_
9. Files and Regular Expressions (A1)
G2*)(&0*B(,#)9%D*$"=*A&77*79,%2*("A*)"*B,%%$*"=)*B"11"2*>&79*#%"B900&2'*),0E0D*0=B(*,0
%9,;&2'*,77*7&290*"%*A"%;0*">*,*>&79*"%*%9,;&2'*,*>&79*B"2),&2&2'*2=1C9%0.
!(,#)9%*/&'(7&'()0R
d Source.fromFile(...).getLines.toArray $&97;0*,77*7&290*">*,*>&79
d Source.fromFile(...).mkString $&97;0*)(9*>&79*B"2)92)0*,0*,*0)%&2'
d <"*B"2:9%)*,*0)%&2'*&2)"*,*2=1C9%D*=09*)(9 toInt "% toDouble 19)(";.
d e09*)(9*?,:, PrintWriter )"*A%&)9*)9H)*>&790
d "regex".r &0*, Regex "CI9B)
d e09 """...""" &>*$"=%*%9'=7,%*9H#%900&"2*B"2),&20*C,BE07,0(90*"%*K=")90
d G>*,*%9'9H*#,))9%2*(,0*'%"=#0D*$"=*9H)%,B)*)(9&%*B"2)92)0*A&)(*)(9*0$2),H for
(regex(var1, ...,varn) <- string)
d <(9 @serializable ,22"),)&"2*1,E90*,*-B,7,*B7,00*09%&,7&p,C79
import io.Source
val source = Source.fromFile("myfile.txt", "UTF-8")
// <(9*>&%0)*,%'=192)*B,2*C9*,*0)%&2'*"%*, java.io.File
// c"=*B,2*"1&)*)(9*92B";&2'*&>*$"=*E2"A*)(,)*)(9*>&79*=090*)(9*;9>,=7)*#7,)>"%1*92B";&2'
val lines = source.getLines
<(9*%90=7)*&0*,2*&)9%,)"%*M099 )(9*n!"779B)&"20o*B(,#)9%N.*c"=*B,2*=09*&)*)"*#%"B900*)(9*7&290
"29*,)*,*)&19R
-"19)&190D*$"=*I=0)*A,2)*)"*%9,;*,2*92)&%9*>&79*&2)"*,*0)%&2'.*<(,)L0*9:92*0&1#79%R
_4
Caution: !,77 close A(92*$"=*,%9*;"29*=0&2'*)(9 Source "CI9B).
67)9%2,)&:97$D*&>*$"=%*>&79*&02L)*7,%'9D*$"=*1,$*I=0)*A,2)*)"*%9,;*&)*&2)"*,*0)%&2'*,2;*#%"B900
)(,)R
"%D
_5
Tip: 89191C9%h$"=*B,2*,7A,$0*=09*)(9 java.util.Scanner B7,00*)"*#%"B900
,*>&79*)(,)*B"2),&20*,*1&H)=%9*">*)9H)*,2;*2=1C9%0.
Y&2,77$D*2")9*)(,)*$"=*B,2*%9,;*2=1C9%0*>%"1*)(9 consoleR
Caution: <(909*19)(";0*,00=19*)(,)*)(9*29H)*&2#=)*7&29*B"2),&20*,*0&2'79
2=1C9%D*A&)("=)*79,;&2'*"%*)%,&7&2'*A(&)90#,B9.*Q)(9%A&09D*,
NumberFormatException "BB=%0.
Caution: b(92*$"=*%9,;*>%"1*,*e8TD*$"=*299;*)"*E2"A*)(9*B(,%,B)9%*09)*&2
,;:,2B9D*#9%(,#0*>%"1*,2*/<<S*(9,;9%.*-99 ())#RiiAAA.AX."%'iG2)9%2,)&"2,7i
QJB(,%09) >"%*1"%9*&2>"%1,)&"2.
_3
in.read(bytes)
in.close()
out.printf("%6d %10.2f",
quantity.asInstanceOf[AnyRef], price.asInstanceOf[AnyRef]) // e'(
>"%*#%&2)&2'*,*1900,'9*)"*)(9*B"20"79.
G)*&0*0&1#79*)"*A%&)9*,*>=2B)&"2*)(,)*#%";=B90*,2*&)9%,)"%*)(%"='(*,77*0=C;&%9B)"%&90*">*,
;&%9B)"%$R
_X
import java.io.File
def subdirs(dir: File): Iterator[File] = {
val children = dir.listFiles.filter(_.isDirectory)
children.toIterator ++ children.toIterator.flatMap(subdirs _)
}
b&)(*)(&0*>=2B)&"2D*$"=*B,2*:&0&)*,77*0=C;&%9B)"%&90*7&E9*)(&0R
import java.nio.file._
implicit def makeFileVisitor(f: (Path) => Unit) = new SimpleFileVisitor[T] {
override def visitFile(p: Path, attrs: attribute.BasicFileAttributes) = {
f(p)
FileVisitResult.CONTINUE
}
}
<(92*$"=*B,2*#%&2)*,77*0=C;&%9B)"%&90*A&)(*)(9*B,77
Q>*B"=%09D*&>*$"=*;"2L)*I=0)*A,2)*)"*#%&2)*)(9*>&790D*$"=*B,2*0#9B&>$*")(9%*,B)&"20*&2*)(9
>=2B)&"2*)(,)*$"=*#,00*)"*)(9 walkFileTree 19)(";.
9.8. Serialization
G2*?,:,D*09%&,7&p,)&"2*&0*=09;*)"*)%,201&)*"CI9B)0*,B%"00*,*29)A"%E*"%*>"%*0("%)J)9%1
0)"%,'9.*MY"%*7"2'J)9%1*0)"%,'9D*09%&,7&p,)&"2*B,2*C9*,AEA,%;h&)*&0*)9;&"=0*)"*;9,7*A&)(
;&>>9%92)*"CI9B)*:9%0&"20*,0*B7,0090*9:"7:9*":9%*)&19.N
/9%9*&0*("A*$"=*;9B7,%9*,*09%&,7&p,C79*B7,00*&2*?,:,*,2;*-B,7,.
?,:,R
_Z
-B,7,R
c"=*09%&,7&p9*,2;*;909%&,7&p9*"CI9B)0*&2*)(9*=0=,7*A,$R
<(9*-B,7,*B"779B)&"20*,%9*09%&,7&p,C79D*0"*$"=*B,2*(,:9*)(91*,0*191C9%0*">*$"=%
09%&,7&p,C79*B7,0090R
G>*)(9*%9'=7,%*9H#%900&"2*B"2),&20*C,BE07,0(90*"%*K="),)&"2*1,%E0D*)(92*&)*&0*,*'"";*&;9,*)"
=09*)(9*n%,Ao*0)%&2'*0$2),H """...""".*Y"%*9H,1#79D
_[
for (matchString <- numPattern.findAllIn("99 bottles, 98 bottles"))
process matchString
Q%*)=%2*)(9*&)9%,)"%*&2)"*,2*,%%,$R
<"*B(9BE*A(9)(9%*)(9*C9'&22&2'*">*,*0)%&2'*1,)B(90D*=09 findPrefixOf.
c"=*B,2*%9#7,B9*)(9*>&%0)*1,)B(D*"%*,77*1,)B(90.
<"*1,)B(*)(9*'%"=#0D*=09*)(9*%9'=7,%*9H#%900&"2*"CI9B)*,0*,2*n9H)%,B)"%o*M099 )(9*nS,))9%2
P,)B(&2'*,2;*!,09*!7,0090o*B(,#)9%ND*7&E9*)(&0R
_\
9.11. Exercises
5. b%&)9*,*-B,7,*B";9*02&##9)*)(,)*%9:9%090*)(9*7&290*&2*,*>&79*M1,E&2'*)(9*7,0)*7&29
)(9*>&%0)*"29D*,2;*0"*"2N.
3. b%&)9*,*-B,7,*#%"'%,1*)(,)*%9,;0*,*>&79*A&)(*),C0D*%9#7,B90*9,B(*),C*A&)(*0#,B90*0"
)(,)*)(9%9*,%9*),C*0)"#0*9:9%$ n B"7=120D*,2;*A%&)90*)(9*%90=7)*)"*)(9*0,19*>&79.
X. b%&)9*,*-B,7,*B";9*02&##9)*)(,)*%9,;0*,*>&79*,2;*#%&2)0*,77*A"%;0*A&)(*1"%9*)(,2
53*B(,%,B)9%0*&2*)(9*>&79*)"*)(9*B"20"79.*WH)%,*B%9;&)*&>*$"=*B,2*;"*)(&0*&2*,*0&2'79
7&29.
Z. b%&)9*,*-B,7,*#%"'%,1*)(,)*%9,;0*,*)9H)*>&79*B"2),&2&2'*"27$*>7",)&2'J#"&2)
2=1C9%0.*S%&2)*)(9*0=1D*,:9%,'9D*1,H&1=1D*,2;*1&2&1=1*">*)(9*2=1C9%0*&2*)(9
>&79.
[. b%&)9*,*-B,7,*#%"'%,1*)(,)*A%&)90*)(9*#"A9%0*">*3*,2;*)(9&%*%9B&#%"B,70*)"*,*>&79D
A&)(*)(9*9H#"292)*%,2'&2'*>%"1*4*)"*34.*T&29*=#*)(9*B"7=120R
1 1
2 0.5
4 0.25
... ...
_]