dsfsfs 发表于 2017-3-2 11:56:12

Scala For Java的一些参考

  变量
  String yourPast = "Good Java Programmer";
  val yourPast : String = "Good Java Programmer"
  val yourPast = "Good Java Programmer"
  var yourFuture = "Good Java Programmer"
  自动类型推断;可变、不可变变量
  class Money(amount:Int) amount不是成员变量
  class Money(val amount:Int)
  val notMuch = new Money(2)
  notMuch.amount
  class Money(var amount:Int)
  val notMuch = new Money(2)
  notMuch.amount=3
  case classes
  public class Money {
  private Integer amount;
  private String currency;
  public Money(Integer amount, String currency) {
  this.amount = amount;
  this.currency = currency;
  }
  public Integer getAmount() {
  return amount;
  }
  public void setAmount(Integer amount) {
  this.amount = amount;
  }
  public String getCurrency() {
  return currency;
  }
  public voidsetCurrency(String currency) {
  this.currency = currency;
  }
  @Override
  public int hashCode() {
  int hash = 5;
  hash = 29 * hash + (this.amount != null ? this.amount.
  hashCode() : 0);
  hash = 29 * hash + (this.currency != null ? this.currency.
  hashCode() : 0);
  return hash;
  }
  @Override
  public boolean equals(Object obj) {
  if (obj == null) {
  return false;
  }
  if (getClass() != obj.getClass()) {
  return false;
  }
  final Money other = (Money) obj;
  return true;
  }
  @Override
  public String toString() {
  return "Money{" + "amount=" + amount + ", currency=" +
  currency + '}';
  }
  public Money add(Money other) {
  return new Money(this.amount +
  other.amount, this.currency);
  }
  }
  case class Money(amount:Int=1, currency:String="USD")two immutable fields the fields declared in Scala classes are public
  case class Money(private val amount: Int, private val currency: String)
  to make them private instead, or usedvar instead ofval to make the fields mutable.
  val defaultAmount = Money()
  val fifteenDollars = Money(15,"USD")
  val fifteenDollars = Money(15)
  val someEuros = Money(currency="EUR")
  case class Money(val amount:Int=1, val currency:String="USD"){
  def +(other: Money) : Money = Money(amount + other.amount)
  }
  Money(12) + Money(34)
  collections
  Scala collections are, by default, immutable
  val numbers = List(1,2,3,4,5,6)
  val reversedList = numbers.reverse
  val onlyAFew = numbers drop 2 take 3
  cons operator
  val numbers = 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: Nil
  val simpleList = Nil.::(6)
  val twoElementsList = List(6).::(5)
  列表串接
  val concatenatedList = simpleList ::: twoElementsList
  val things = List(0,1,true) AnyVal
  val things = List(0,1,true,"false") Any
  复杂对象列表
  val amounts = List(Money(10,"USD"),Money(2,"EUR"),Money(20,"GBP"),
  Money(75,"EUR"),Money(100,"USD"),Money(50,"USD"))
  Filter
  val euros = amounts.filter(money => money.currency=="EUR")
  val euros = amounts.filter(x => x.currency=="EUR")
  val euros = amounts.filter(_.currency=="EUR")
  partition
  val allAmounts = amounts.partition(amt => amt.currency=="EUR")
  Tuples
  val euros = allAmounts._1
  val everythingButEuros= allAmounts._2
  val (euros,everythingButEuros) = amounts.partition(amt => amt.currency=="EUR")
  Map
  Map amounts = new HashMap<String,Integer>();
  amounts.put("USD", 10);
  amounts.put("EUR", 2);
  val wallet = Map( "USD" -> 10, "EUR" -> 2 )
  val someEuros = wallet("EUR")
  Option类型
  val mayBeSomePounds = wallet.get("GBP")
  val updatedWallet = wallet + ("GBP" -> 20)新的不可变
  val tenDollars = "USD"-> 10 Tuple
  def increment = (x:Int) => x + 1
  List(1,2,3,4).map(increment)
  List(1,2,3,4) map increment
  String Interpolation
  val many = 10000.2345
  val amount = s"$many euros"
  格式化宽度
  val amount = f"$many%12.2f euros"
  val amount = s"${many*2} euros"
  val printedAmounts = amounts map(m=> s"${m.amount} ${m.currency}")
  groupBy
  groupBy method that transforms a collection into aMap collection:
  val sortedAmounts = amounts groupBy(_.currency)
  Scala UnitTest
  POM.xml maven依赖文件
  ·Dependency for the core scala-library:
  <dependency>
  <groupId>org.scala-lang</groupId>
  <artifactId>scala-library</artifactId>
  <version>2.10.0</version>
  </dependency>
  ·Dependency for scalatest (a framework for testing in Scala that supports
  JUnit and other styles; we will cover it in detail in Chapter 4, Testing Tools):
  <dependency>
  <groupId>org.scalatest</groupId>
  <artifactId>scalatest_2.10</artifactId>
  <version>2.0/version>
  <scope>test</scope>
  </dependency>
  ·Dependency for JUnit to use JavaAssert statements in our test case:
  <dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
  </dependency>
  scala-maven-plugin
  <plugin>
  <groupId>net.alchim31.maven</groupId>
  <artifactId>scala-maven-plugin</artifactId>
  <executions>
  <execution>
  <id>scala-compile-first</id>
  <phase>process-resources</phase>
  <goals>
  <goal>add-source</goal>
  <goal>compile</goal>
  </goals>
  </execution>
  <execution>
  <id>scala-test-compile</id>
  <phase>process-test-resources</phase>
  <goals>
  <goal>testCompile</goal>
  </goals>
  </execution>
  </executions>
  </plugin>
  单元测试代码
  import org.junit._
  import Assert._
  class CustomerScalaTest {
  @Before
  def setUp: Unit = {
  }
  @After
  def tearDown: Unit = {
  }
  @Test
  def testGetCustomerId = {
  System.out.println("getCustomerId")
  val instance = new Customer()
  val expResult: Integer = null
  val result: Integer = instance.getCustomerId()
  assertEquals(expResult, result)
  }
  }
  Java/Scala Collection转换
  ./activator console
  import java.util.Arrays
  val javaList = Arrays.asList(1,2,3,4)
  import scala.collection.JavaConverters._
  val scalaList = javaList.asScala
  val javaListAgain = scalaList.asJava
  assert( javaList eq javaListAgain)
  JavaBean-style properties
  class Company(var name:String)
  val sun = new Company("Sun Microsystems")
  sun.name
  sun.name_=("Oracle")
  import scala.beans.BeanProperty
  class Company(@BeanProperty var name:String)
  val sun = new Company("Sun Microsystems")
  sun.getName()
  sun.setName("Oracle")
  OO
  class Customer ( var customerId: Int, var zip: String) {
  def this( zip: String) = this(0,zip)
  def getCustomerId() = customerId
  def setCustomerId(cust: Int): Unit = {
  customerId = cust
  }
  }
  val customer = new Customer("123 45")
  traits
  interface VIPCustomer {
  Integer discounts();
  }
  class Customer(val name:String, val discountCode:String="N" ){
  def discounts() : List = List(5)
  override def toString() = "Applied discounts: " + discounts.mkString(" ","%, ","% ")
  }
  trait VIPCustomer extends Customer {
  override def discounts = super.discounts ::: List(10)
  }
  trait GoldCustomer extends Customer {
  override def discounts =
  if (discountCode.equals("H"))
  super.discounts ::: List(20)
  else super.discounts ::: List(15)
  }
  object Main {
  def main(args: Array) {
  val myDiscounts = new Customer("Thomas","H") with VIPCustomer with GoldCustomer
  println(myDiscounts)
  }
  }
  scala> Main.main(Array.empty)
  Applied discounts: 5%, 10%, 20%
  Note that the order in which traits are stacked is important. They are calling each other from right to left.GoldCustomer is, therefore, the first one to be called.
  Static
  companion objects
  object Main {
  def main(args: Array) {
  println("Hello Scala World !")
  }
  }
  object Customer {
  def apply()= new Customer("default name")
  }
  class Customer(name:String) {
  …
  }
  exceptions
  public class ConversionSample {
  static Integer parse(String numberAsString) {
  Integer number = null;
  try {
  number = Integer.parseInt(numberAsString);
  } catch (NumberFormatExceptionnfe) {
  System.err.println("Wrong format for "+numberAsString);
  } catch (Exception ex) {
  System.err.println("An unknown Error has occurred");
  }
  System.out.println("Parsed Number: "+number);
  return number;
  }
  def parse(numberAsString: String) =
  try {
  Integer.parseInt(numberAsString)
  } catch {
  case nfe: NumberFormatException =>
  println("Wrong format for number "+numberAsString)
  case e: Exception => println("Error when parsing number"+
  numberAsString)
  }
  返回值
  case nfe: NumberFormatException =>
  println("Wrong format for number "+numberAsString); -1
  case _: Throwable =>
  println("Error when parsing number "+numberAsString)
  -1
  scala.util.Left orscala.util.Right type
  case class Failure(val reason: String)
  def parse(numberAsString: String) : Either =
  try {
  val result = Integer.parseInt(numberAsString)
  Right(result)
  } catch {
  case _ : Throwable => Left(Failure("Error when parsing
  number"))
  }
  String customerLevel = null;
  if(amountBought > 3000) {
  customerLevel = "Gold";
  } else {
  customerLevel = "Silver";
  }
  val amountBought = 5000
  val customerLevel = if (amountBought> 3000) "Gold" else "Silver"
  Scala的代码风格
  IDE
  http://docs.scala-lang.org/style/
  Eclipse-based (including all the different versions of Eclipse, Typesafe's own bundled version known as Scala IDE as well as more commercial IDEs such as SpringSourceSTS), IntelliJ IDEA, and NetBeans.
  SBT
  Simple Build Tool (SBT) http://www.scala-sbt.org/
  http://www.scala-sbt.org/0.13/tutorial/Hello.html 例子
  http://www.scala-sbt.org/0.13/tutorial/Directories.html 目录结构,Build.sbt是sbt的定义文件
  SBT plugins
  https://github.com/typesafehub/sbteclipse 基于sbt生成eclipse使用的工程文件
  https://github.com/mpeltonen/sbt-idea 基于sbt生成IntelliJ使用的工程文件
  https://github.com/dcaoyuan/nbscala/wiki/SbtIntegrationInNetBeans 基于sbt生成Netbeans使用的工程文件
  plugins.sbt中修改以生成
  xsbt-web-plugin (available athttps://github.com/JamesEarlDouglas/xsbt-web-plugin ), a useful plugin to create traditional web apps that runs on a servlet container (such as Jetty).
  v Plugins.sbt: addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "0.4.2")
  Build.sbt:
  name := "SampleProject"
  organization := "com.samples"
  version := "1.0"
  scalaVersion := "2.10.3"
  seq(webSettings :_*)
  libraryDependencies += "org.mortbay.jetty" % "jetty" % "6.1.22" % "container"
  libraryDependencies += "javax.servlet" % "servlet-api" % "2.5" % "provided"
  v sbt eclipse生成了eclipse工程
  v 启动web工程
  > sbt
  > container:start
  v War包生成 > package
  sbt-assembly
  https://github.com/sbt/sbt-assembly
  v Plugins.sbt addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
  v assembly.sbt
  import AssemblyKeys._ // put this at the top of the file
  assemblySettings
  // your assembly settings here
  Scalariform
  plugins.sbt
  addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.2.0")
  SBT中运行compile ortest:compile时,即按照scala风格格式化代码
  Scala Worksheets
  Eclipse中建立的菜单

  每次保存时,可以看到执行的结果

  Java基础库上scala的封装例子
  http://dispatch.databinder.net/Dispatch.html HttpClient上的封装
  build.sbt添加libraryDependencies += "net.databinder.dispatch" %% "dispatch-core" % "0.11.0"
  import dispatch._, Defaults._
  val request = url("http://freegeoip.net/xml/www.google.com")
  val result = Http( request OK as.String)
  val resultAsString = result()
  def printer = new scala.xml.PrettyPrinter(90, 2)
  for (xml <- citiesAsXML)
  println(printer.format(xml))
  for comprehension orfor expression
  for (sequence) yield expression In the preceding code,sequence can contain the following components:
  ·Generators: They drive the iteration and are written in the following form:
  element <- collection
  ·Filters: They control the iteration and are written in the following form:
  if expression
  ·Definitions: They are local variable definitions and are written in the
  following form:
  variable = expression
  for {
  elem <- List(1,2,3,4,5)
  } yield "T" + elem
  for {
  word <- List("Hello","Scala")
  char <- word
  } yield char.isLower
  for {
  word <- List("Hello","Scala")
  char <- word if char.isUpper
  } yield char
  or {
  word <- List("Hello","Scala")
  char <- word
  lowerChar = char.toLower
  } yield lowerChar
  测试
  ScalaTest ( www.scalatest.org ) and Specs2 ( etorreborre.github.io/specs2/ ). ScalaCheck framework ( www.scalacheck.org )
  Typesafe Activator包含必要的插件,项目根下执行> activator eclipse即生成eclipse工程
  import org.scalatest.FunSuite
  class Test01 extends FunSuite {
  test("Very Basic") {
  assert(1 == 1)
  }
  test("Another Very Basic") {
  assert("Hello World" == "Hello World")
  }
  }
  > activator
  > test-only scalatest.Test01 (or scalatest.Test01.scala)
  >~test-only scalatest.Test02文件修改后自动运行单元测试【continuous mode】
  The continuous mode works for the other SBT commands as well, such as~run or~test
  作为Junit的单元测试方式运行
  import org.junit.runner.RunWith
  import org.scalatest.junit.JUnitRunner
  import org.scalatest.FunSuite
  @RunWith(classOf)
  class MyTestSuite extends FunSuite ...
  www.seleniumhq.org 功能测试
  package scalatest
  import org.scalatest._
  import org.scalatest.selenium.WebBrowser
  import org.openqa.selenium.htmlunit.HtmlUnitDriver
  import org.openqa.selenium.firefox.FirefoxDriver
  import org.openqa.selenium.WebDriver
  class Test08 extends FlatSpec with Matchers with WebBrowser {
  implicit val webDriver: WebDriver = new HtmlUnitDriver
  go to "http://www.amazon.com"
  click on "twotabsearchtextbox"
  textField("twotabsearchtextbox").value = "Scala"
  submit()
  pageTitle should be ("Amazon.com: Scala")
  pageSource should include("Scala Cookbook: Recipes")
  }
  www.scalamock.org
  Web框架
  alternatives to create web applications range from lightweight frameworks such as Unfiltered, Spray, or Scalatra to full-featured solutions such as the Lift or the Play Frameworks.
  http://www.playframework.com/ http://www.playmodules.net

  Web Service
  Plugins.sbt
  addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" %"2.4.0")
  addSbtPlugin("org.scalaxb" % "sbt-scalaxb" % "1.1.2")
  resolvers += Resolver.sonatypeRepo("public")
  build.sbt
  import ScalaxbKeys._
  name:="wssample"
  scalaVersion:="2.10.2"
  scalaxbSettings
  ibraryDependencies += "net.databinder.dispatch" %% "dispatch-core" %"0.11.0"
  libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M7" %"test"
  sourceGenerators in Compile <+= scalaxb in Compile
  packageName in scalaxb in Compile := "se.wssample"
  XML/JSON
  val books =
  <Library>
  <book title="Programming in Scala" quantity="15" price="30.00"
  />
  <book title="Scala for Java Developers" quantity="10"
  price="25.50" />
  </Library>
  import scala.xml._
  val sameBooks = XML.loadString("""
  <Library>
  <book title="Programming in Scala" quantity="15"
  price="30.00"/>
  <book title="Scala for Java Developers" quantity="10"
  price="25.50"/>
  </Library>
  """)
  val total = (for {
  book <- books \ "book"
  price = ( book \ "@price").text.toDouble
  quantity = ( book \ "@quantity").text.toInt
  } yield price * quantity).sum
  val books =
  <Library>
  { List("Programming in Scala,15,30.00","Scala for Java
  Developers,10,25.50") map { row => row split "," } map { b => <book
  title={b(0)} quantity={b(1)} price={b(2)} /> }}
  </Library>
  import scala.util.parsing.json._
  val result = JSON.parseFull("""
  {
  "Library": {
  "book": [
  {
  "title": "Scala for Java Developers",
  "quantity": 10
  },
  {
  "title": "Programming Scala",
  "quantity": 20
  }
  ]}
  }
  """)
  Futures and Promises
  Scala Improvement Process (SIP)SIP-14-Futures and Promises
  http://en.wikipedia.org/wiki/Futures_and_promises
  ·async { <expression> } : In this construct,<expression> is the code to
  be executed asynchronously.
  ·await { <expression returning a Future> } : This construct is included
  in anasync block. It suspends the execution of the enclosingasync block
  until the argumentFuture is completed.
  async future
  Actor
  Reactive Systems
  http://www.reactivemanifesto.org/
  反应式编程
  Misc
  MongoDB database, we are going to discover how the Casbah Scala toolkit https://github.com/mongodb/casbah
  RPEL模式下拷贝部分代码运行
  scala> :paste
  // Entering paste mode (ctrl-D to finish)
页: [1]
查看完整版本: Scala For Java的一些参考