Scala 代码看起来更简单/行数更少的 Scala 和 Java 代码示例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2952732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:53:07  来源:igfitidea点击:

Samples of Scala and Java code where Scala code looks simpler/has fewer lines?

javascalacomparisonlanguage-features

提问by Roman

I need some code samples (and I also really curious about them) of Scala and Java code which show that Scala code is more simple and concise then code written in Java (of course both samples should solve the same problem).

我需要一些 Scala 和 Java 代码的代码示例(我也对它们很好奇),它们表明 Scala 代码比用 Java 编写的代码更简单和简洁(当然这两个示例都应该解决相同的问题)。

If there is only Scala sample with comment like "this is abstract factory in Scala, in Java it will look much more cumbersome" then this is also acceptable.

如果只有带有注释的 Scala 示例,例如“这是 Scala 中的抽象工厂,在 Java 中它看起来会更麻烦”,那么这也是可以接受的。

Thanks!

谢谢!

I like most of all accepted and thisanswers

我最喜欢接受这个答案

采纳答案by Esko Luontola

Let's improve stacker's exampleand use Scala's case classes:

让我们改进stacker 的示例并使用 Scala 的案例类

case class Person(firstName: String, lastName: String)

The above Scala class contains all features of the below Java class, and some more- for example it supports pattern matching(which Java doesn't have). Scala 2.8 adds named and default arguments, which are used to generate a copy methodfor case classes, which gives the same ability as the with* methods of the following Java class.

上面的 Scala 类包含下面 Java 类的所有功能,还有一些- 例如它支持模式匹配(Java 没有)。Scala 2.8 添加了命名和默认参数,用于为 case 类生成复制方法,它提供与以下 Java 类的 with* 方法相同的功能。

public class Person implements Serializable {
    private final String firstName;
    private final String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Person withFirstName(String firstName) {
        return new Person(firstName, lastName);
    }

    public Person withLastName(String lastName) {
        return new Person(firstName, lastName);
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Person person = (Person) o;
        if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) {
            return false;
        }
        if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) {
            return false;
        }
        return true;
    }

    public int hashCode() {
        int result = firstName != null ? firstName.hashCode() : 0;
        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
        return result;
    }

    public String toString() {
        return "Person(" + firstName + "," + lastName + ")";
    }
}

Then, in usage we have (of course):

然后,在使用中我们有(当然):

Person mr = new Person("Bob", "Dobbelina");
Person miss = new Person("Roberta", "MacSweeney");
Person mrs = miss.withLastName(mr.getLastName());

Against

反对

val mr = Person("Bob", "Dobbelina")
val miss = Person("Roberta", "MacSweeney")
val mrs = miss copy (lastName = mr.lastName)

回答by stacker

I found this one impressive

我发现这个令人印象深刻

Java

爪哇

public class Person {
    private final String firstName;
    private final String lastName;
    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
}

Scala

斯卡拉

class Person(val firstName: String, val lastName: String)

As well as these ones (sorry for not pasting, I didn't want to steal the code)

以及这些(抱歉没有粘贴,我不想窃取代码)

回答by dbyrne

Lazily evaluated infinite streams are a good example:

惰性求值的无限流就是一个很好的例子:

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

}

Here is a question addressing infinite streams in Java: Is an infinite iterator bad design?

这是一个解决 Java 中无限流的问题:无限迭代器设计不好?

Another good example are first class functions and closures:

另一个很好的例子是一流的函数和闭包:

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 doesn't support first class functions, and mimicking closures with anonymous inner classes isn't very elegant. Another thing this example shows that java can't do is running code from an interpreter/REPL. I find this immensely useful for quickly testing code snippets.

Java 不支持一等函数,并且用匿名内部类模仿闭包不是很优雅。这个例子表明java不能做的另一件事是从解释器/REPL运行代码。我发现这对于快速测试代码片段非常有用。

回答by Thomas

This is a very simple example: Square integers and then add them

这是一个非常简单的例子:平方整数,然后将它们相加


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

In scala:

在斯卡拉:


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)

Compact map applies the function to all elements of the array, so:

紧凑映射将该函数应用于数组的所有元素,因此:

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

Fold left is will start with 0 as the accumulator (s) and apply add(s,i)to all the elements (i) of the array, so that:

向左折叠将从 0 开始作为累加器 (s) 并应用于add(s,i)数组的所有元素 (i),因此:

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

Now this can be further compacted to:

现在可以进一步压缩为:

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

This one I will not try in Java (to much work), turn XML to a Map:

这个我不会在 Java 中尝试(做很多工作),将 XML 转换为 Map:


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

Another one liner to get the map from the XML:

另一个从 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)

回答by Don Mackenzie

How about Quicksort?

快排怎么样?



Java

爪哇

The following is a java example found via a google search,

以下是通过谷歌搜索找到的java示例,

the URL is http://www.mycstutorials.com/articles/sorting/quicksort

URL 是http://www.mycstutorials.com/articles/sorting/quicksort

public void quickSort(int array[]) 
// pre: array is full, all elements are non-null integers
// post: the array is sorted in ascending order
{
   quickSort(array, 0, array.length - 1);   // quicksort all the elements in the array
}


public void quickSort(int array[], int start, int end)
{
   int i = start;      // index of left-to-right scan
   int k = end;        // index of right-to-left scan

   if (end - start >= 1)               // check that there are at least two elements to sort
   {
       int pivot = array[start];       // set the pivot as the first element in the partition

       while (k > i)                   // while the scan indices from left and right have not met,
       {
           while (array[i] <= pivot && i <= end && k > i) // from the left, look for the first
              i++;                                        // element greater than the pivot
           while (array[k] > pivot && k >= start && k >= i) // from the right, look for the first
              k--;                                          // element not greater than the pivot
           if (k > i)                  // if the left seekindex is still smaller than
               swap(array, i, k);      // the right index, swap the corresponding elements
       }
       swap(array, start, k);          // after the indices have crossed, swap the last element in
                                       // the left partition with the pivot 
       quickSort(array, start, k - 1); // quicksort the left partition
       quickSort(array, k + 1, end);   // quicksort the right partition
    }
    else // if there is only one element in the partition, do not do any sorting
    {
        return;                        // the array is sorted, so exit
    }
}

public void swap(int array[], int index1, int index2) 
// pre: array is full and index1, index2 < array.length
// post: the values at indices 1 and 2 have been swapped
{
   int temp      = array[index1];      // store the first value in a temp
   array[index1] = array[index2];      // copy the value of the second into the first
   array[index2] = temp;               // copy the value of the temp into the second
}


Scala

斯卡拉

A quick attempt at a Scala version. Open season for code improvers ;@)

Scala 版本的快速尝试。代码改进者开放季;@)

def qsort(l: List[Int]): List[Int] = {
  l match {
    case Nil         => Nil
    case pivot::tail => qsort(tail.filter(_ < pivot)) ::: pivot :: qsort(tail.filter(_ >= pivot))
  }
}

回答by missingfaktor

Task:Write a program to index a list of keywords (like books).

任务:编写一个程序来索引关键字列表(如书籍)。

Explanation:

解释:

  • Input: List<String>
  • Output: Map<Character, List<String>>
  • The key of map is 'A' to 'Z'
  • Each list in the map are sorted.
  • 输入:列表<字符串>
  • 输出:地图<字符,列表<字符串>>
  • 地图的关键是“A”到“Z”
  • 地图中的每个列表都已排序。

Java:

爪哇:

import java.util.*;

class Main {
  public static void main(String[] args) {
    List<String> keywords = Arrays.asList("Apple", "Ananas", "Mango", "Banana", "Beer"); 
    Map<Character, List<String>> result = new HashMap<Character, List<String>>(); 
    for(String k : keywords) {   
      char firstChar = k.charAt(0);     
      if(!result.containsKey(firstChar)) {     
        result.put(firstChar, new  ArrayList<String>());   
      }     
      result.get(firstChar).add(k); 
    } 
    for(List<String> list : result.values()) {   
      Collections.sort(list); 
    }
    System.out.println(result);         
  }
}

Scala:

斯卡拉:

object Main extends App {
  val keywords = List("Apple", "Ananas", "Mango", "Banana", "Beer")
  val result = keywords.sorted.groupBy(_.head)
  println(result)
}

回答by Arjan Blokzijl

I liked this simple example of sorting and transformation, taken from David Pollak's 'Beginning Scala' book:

我喜欢这个简单的排序和转换示例,摘自 David Pollak 的“Beginning Scala”一书中:

In Scala:

在斯卡拉:

def validByAge(in: List[Person]) = in.filter(_.valid).sortBy(_.age).map(_.first)
case class Person(val first: String, val last: String, val age: Int) {def valid: Boolean = age > 18}
validByAge(List(Person("John", "Valid", 32), Person("John", "Invalid", 17), Person("OtherJohn", "Valid", 19)))

In Java:

在 Java 中:

public static List<String> validByAge(List<Person> in) {
   List<Person> people = new ArrayList<Person>();
   for (Person p: in) {
     if (p.valid()) people.add(p);
   }
   Collections.sort(people, new Comparator<Person>() {
      public int compare(Person a, Person b) {
        return a.age() - b.age();
      } 
   } );
   List<String> ret = new ArrayList<String>();
     for (Person p: people) {
       ret.add(p.first);
     }
   return ret;
}

public class Person {
    private final String firstName;
    private final String lastName;
    private final Integer age;
    public Person(String firstName, String lastName, Integer age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    public String getFirst() {
        return firstName;
    }
    public String getLast() {
        return lastName;
    }
    public Integer getAge() {
       return age;
    }
    public Boolean valid() {
       return age > 18;
    }
}

List<Person> input = new ArrayList<Person>();
input.add(new Person("John", "Valid", 32));
input.add(new Person("John", "InValid", 17));
input.add(new Person("OtherJohn", "Valid", 19));

List<Person> output = validByAge(input)

回答by Vasil Remeniuk

Problem:you need to design a method that will execute any given code asynchronously.

Solution in Java:

问题:您需要设计一个方法来异步执行任何给定的代码。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
            }
});

The same thing in Scala(using actors):

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    
}

回答by JUST MY correct OPINION

This Scala code...

这个Scala代码...

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))
  })
}

...would be completely unreadable in Java, if possible at all.

...如果可能的话,在 Java 中将完全不可读。

回答by OscarRyz

Why nobody posted this before:

为什么之前没有人发过这个:

Java:

爪哇:

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

116 characters.

116 个字符。

Scala:

斯卡拉:

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

56 characters.

56 个字符。