Образцы кода Scala и Java, где код Scala выглядит проще / имеет меньше строк? - PullRequest
91 голосов
/ 01 июня 2010

Мне нужны некоторые примеры кода (и мне тоже очень любопытно) кода Scala и Java, которые показывают, что код Scala более прост и лаконичен, чем код, написанный на Java (конечно, оба примера должны решить одну и ту же проблему).

Если есть только пример Scala с комментарием типа «это абстрактная фабрика в Scala, в Java это будет выглядеть намного более громоздким», то это также допустимо.

Спасибо!

Мне больше всего нравятся принятые и эти ответы

Ответы [ 18 ]

6 голосов
/ 07 июня 2010

Мне понравился user unknown's answer , поэтому я постараюсь улучшить его. Приведенный ниже код не является прямым переводом примера Java, но он выполняет ту же задачу с тем же API.

def wordCount (sc: Scanner, delimiter: String) = {
  val it = new Iterator[String] {
    def next = sc.nextLine()
    def hasNext = sc.hasNextLine()
  }
  val words = it flatMap (_ split delimiter iterator)
  words.toTraversable groupBy identity mapValues (_.size)
}
5 голосов
/ 02 июня 2010

Проблема: вам необходимо разработать метод, который будет выполнять любой данный код асинхронно.

Решение в Java :

/**
* This method fires runnables asynchronously
*/
void execAsync(Runnable runnable){
    Executor executor = new Executor() {
        public void execute(Runnable r) {
            new Thread(r).start();
        }
    };
    executor.execute(runnable);
}

...

execAsync(new Runnable() {
            public void run() {
                ...   // put here the code, that need to be executed asynchronously
            }
});

То же самое в Scala (с использованием актеров):

def execAsync(body: => Unit): Unit = {
  case object ExecAsync    
  actor {
    start; this ! ExecAsync
    loop {
      react {           
        case ExecAsync => body; stop
      }
    }
  }    
}

...

execAsync{  // expressive syntax - don't need to create anonymous classes
  ...  // put here the code, that need to be executed asynchronously    
}
5 голосов
/ 02 июня 2010

Это очень простой пример: квадратные целые числа, а затем добавьте их


    public int sumSquare(int[] list) {
        int s = 0;
        for(int i = 0; i < list.length; i++) {
            s += list[i] * list[i]; 
        }
        return s;
    }

В скале:


val ar = Array(1,2,3)
def square(x:Int) = x * x
def add(s:Int,i:Int) = s+i

ar.map(square).foldLeft(0)(add)

Компактная карта применяет функцию ко всем элементам массива, поэтому:

Array(1,2,3).map(square)
Array[Int] = Array(1, 4, 9)

Свернуть влево будет начинаться с 0 в качестве аккумулятора (ов) и применять add(s,i) ко всем элементам (i) массива, так что:

 Array(1,4,9).foldLeft(0)(add)  // return 14 form 0 + 1 + 4 + 9

Теперь это может быть дополнительно сжато до:

Array(1,2,3).map(x => x * x ).foldLeft(0)((s,i) => s + i )

Это я не буду пытаться в Java (для большой работы), превратить XML в карту:


<a>
   <b id="a10">Scala</b>
   <b id="b20">rules</b>
</a>

Еще один лайнер для получения карты из XML:


val xml = <a><b id="a10">Scala</b><b id="b20">rules</b></a>

val map = xml.child.map( n => (n \ "@id").text -> n.child.text).toMap
// Just to dump it.
for( (k,v) <- map) println(k + " --> " + v)
3 голосов
/ 05 июня 2010

Шаблон выключателя из Выпуск Майкла Найгарда It in FaKods ( ссылка на код )

реализация выглядит так в Scala:

. . .
addCircuitBreaker("test", CircuitBreakerConfiguration(100,10))
. . .


class Test extends UsingCircuitBreaker {
  def myMethodWorkingFine = {
    withCircuitBreaker("test") {
      . . .
    }
  }

  def myMethodDoingWrong = {
    withCircuitBreaker("test") {
      require(false,"FUBAR!!!")
    }
  }
}

Который я считаю очень хорошим. Это выглядит как кусочек языка, но это простой микс в CircuitBreaker Object , выполняющий всю работу.

/**
 * Basic MixIn for using CircuitBreaker Scope method
 *
 * @author Christopher Schmidt
 */
trait UsingCircuitBreaker {
  def withCircuitBreaker[T](name: String)(f: => T): T = {
    CircuitBreaker(name).invoke(f)
  }
}

Ссылка на других языках Google для "Автоматический выключатель" + ваш язык.

2 голосов
/ 24 апреля 2012

Я готовлю документ, который приводит несколько примеров кода Java и Scala, используя только простые для понимания функции Scala:

Scala: лучшая Java

Если вы хотите, чтобы я что-то добавил к этому, пожалуйста, ответьте в комментариях.

2 голосов
/ 02 июня 2010

Почему никто не опубликовал это раньше:

Java:

class Hello {
     public static void main( String [] args ) {
          System.out.println("Hello world");
     }
}

116 символов.

Scala:

object Hello extends App {
     println("Hello world")
}

56 символов.

1 голос
/ 01 июня 2010

Хороший пример - лениво вычисленные бесконечные потоки:

object Main extends Application {

   def from(n: Int): Stream[Int] = Stream.cons(n, from(n + 1))

   def sieve(s: Stream[Int]): Stream[Int] =
     Stream.cons(s.head, sieve(s.tail filter { _ % s.head != 0 }))

   def primes = sieve(from(2))

   primes take 10 print

}

Вот вопрос, обращающийся к бесконечным потокам в Java: Является ли бесконечный итератор плохим дизайном?

Другим хорошим примером являются функции первого класса и замыкания:

scala> def f1(w:Double) = (d:Double) => math.sin(d) * w
f1: (w: Double)(Double) => Double

scala> def f2(w:Double, q:Double) = (d:Double) => d * q * w
f2: (w: Double,q: Double)(Double) => Double

scala> val l = List(f1(3.0), f2(4.0, 0.5))
l: List[(Double) => Double] = List(<function1>, <function1>)

scala> l.map(_(2))
res0: List[Double] = List(2.727892280477045, 4.0)

Java не поддерживает функции первого класса, и имитация замыканий с анонимными внутренними классами не очень элегантна. В этом примере показано, что java не может сделать это запуск кода из интерпретатора / REPL. Я считаю это чрезвычайно полезным для быстрого тестирования фрагментов кода.

0 голосов
/ 02 июня 2010

Этот код Скала ...

def partition[T](items: List[T], p: (T, T) => Boolean): List[List[T]] = {
  items.foldRight[List[List[T]]](Nil)((item: T, items: List[List[T]]) => items match {
    case (first :: rest) :: last if p (first, item) =>
      (List(item)) :: (first :: rest) :: last
    case (first :: rest) :: last =>
      (item :: first :: rest) :: last
    case _ => List(List(item))
  })
}

... было бы совершенно нечитаемым в Java, если вообще возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...