Scala 코드가 Java로 작성된 코드보다 더 간단하고 간결하다는 것을 보여주는 Scala 및 Java 코드의 일부 코드 샘플이 필요합니다 (물론 두 샘플 모두 동일한 문제를 해결해야 함).
"이것은 Scala의 추상 팩토리입니다. Java에서는 훨씬 더 번거롭게 보일 것입니다"와 같은 주석이있는 Scala 샘플 만있는 경우에도 허용됩니다.
감사!
나는 대부분의 수락을 좋아 하고이 답변
Scala 코드가 Java로 작성된 코드보다 더 간단하고 간결하다는 것을 보여주는 Scala 및 Java 코드의 일부 코드 샘플이 필요합니다 (물론 두 샘플 모두 동일한 문제를 해결해야 함).
"이것은 Scala의 추상 팩토리입니다. Java에서는 훨씬 더 번거롭게 보일 것입니다"와 같은 주석이있는 Scala 샘플 만있는 경우에도 허용됩니다.
감사!
나는 대부분의 수락을 좋아 하고이 답변
답변:
스태커의 예제를 개선 하고 Scala의 케이스 클래스를 사용 합시다 .
case class Person(firstName: String, lastName: String)
스칼라 클래스 위는 자바 아래 클래스의 모든 기능을 포함, 몇 가지 더 - 예를 들면가 지원하는 패턴 매칭을 (자바하지 않습니다). Scala 2.8 은 케이스 클래스에 대한 복사 메소드 를 생성하는 데 사용되는 명명 된 기본 인수를 추가합니다 . 이는 다음 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 + ")";
}
}
그런 다음 사용법에서 (물론) :
Person mr = new Person("Bob", "Dobbelina");
Person miss = new Person("Roberta", "MacSweeney");
Person mrs = miss.withLastName(mr.getLastName());
에 맞서
val mr = Person("Bob", "Dobbelina")
val miss = Person("Roberta", "MacSweeney")
val mrs = miss copy (lastName = mr.lastName)
case class Person(val firstName: String, val lastName: String)
무엇을해야합니까? 비공개로 만드는 것도 가능하지만 미적용 등으로 인해 이치에 맞지 않습니다.
case class Person(private val firstName: String)
이지만 케이스 클래스를 사용해서는 안됩니다. 대신 수행 class Person(firstName: String)
하고 firstName
기본적으로 비공개입니다.
val
와 private val
접근 방법의 여부, 즉이다 firstName()
하고 firstName(String)
, 공개 또는 비공개. Scala에서 필드는 항상 비공개입니다. Scala가 Java 스타일 get / set 메서드 (Scala 스타일 접근 자에 추가하여)를 생성하려면 @BeanProperty
주석이 있습니다.
이건 인상적 이었어
자바
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;
}
}
스칼라
class Person(val firstName: String, val lastName: String)
뿐만 아니라 (붙여 넣지 않아서 죄송합니다. 코드를 훔치고 싶지 않았습니다)
getFirstName
및 getLastName
메서드를 생성하지 않습니다 . 이를 위해 매개 변수에 scala.reflect.BeanProperty
주석을 달아야합니다.
get
. 관용적 Java 코드는 관용적 Scala 코드와 다릅니다. 때로는 is
접두어는 논리 값에 사용됩니다. davetron5000.github.com/scala-style/naming_conventions/methods/…
case class
얻을 수 있습니다 (그리고 당신은 또한 명시 적으로 논쟁을 할 필요가 없습니다 ) :toString
equals
hashCode
val
case class Person(firstName: String, lastName: String)
case class
, 아니 단지 class
.
과제 : 책과 같은 키워드 목록을 색인화하는 프로그램을 작성하십시오.
설명:
자바:
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);
}
}
스칼라 :
object Main extends App {
val keywords = List("Apple", "Ananas", "Mango", "Banana", "Beer")
val result = keywords.sorted.groupBy(_.head)
println(result)
}
직무:
및 필드가 people
있는 클래스의 객체 목록 Person
이 있습니다 . 이 목록을 먼저별로 정렬 한 다음별로 정렬해야합니다 .name
age
name
age
자바 7 :
Collections.sort(people, new Comparator<Person>() {
public int compare(Person a, Person b) {
return a.getName().compare(b.getName());
}
});
Collections.sort(people, new Comparator<Person>() {
public int compare(Person a, Person b) {
return Integer.valueOf(a.getAge()).compare(b.getAge());
}
});
스칼라 :
val sortedPeople = people.sortBy(p => (p.name, p.age))
이 답변을 작성한 이후로 상당한 진전이있었습니다. 람다 (및 메서드 참조)가 마침내 Java에 상륙했으며 Java 세계를 강타하고 있습니다.
위 코드는 Java 8 (@fredoverflow 제공)에서 다음과 같이 표시됩니다 .
people.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));
이 코드는 거의 짧지 만 Scala만큼 우아하게 작동하지는 않습니다.
스칼라 용액에서, Seq[A]#sortBy
방법은 기능을 허용 할 필요가 있다 를 . 유형 클래스입니다. 두 세계 모두를 가장 잘 생각하십시오. 예를 들어 , 문제의 유형에 대해 암시 적이지만 , 확장 가능하고없는 유형에 소급 적으로 추가 할 수 있습니다. Java에는 유형 클래스가 없기 때문에 이러한 모든 메서드 를 . 예를 들어 및 여기를 참조 하십시오 .A => B
B
Ordering
Ordering
Comparable
Comparator
Comparable
Comparator
comparing
thenComparing
유형 클래스를 사용하면 "A에 순서가 있고 B에 순서가 있으면 튜플 (A, B)에도 순서가 있습니다."와 같은 규칙을 작성할 수 있습니다. 코드에서는 다음과 같습니다.
implicit def pairOrdering[A : Ordering, B : Ordering]: Ordering[(A, B)] = // impl
이것이 sortBy
우리 코드에서 이름과 나이를 비교 하는 방법 입니다. 이러한 의미는 위의 "규칙"으로 인코딩됩니다. Scala 프로그래머는 이것이 이런 식으로 작동 할 것이라고 직관적으로 예상 할 것입니다. 와 같은 특수 목적 방법 comparing
을에 추가 할 필요가 없습니다 Ordering
.
람다와 메서드 참조는 함수형 프로그래밍 인 빙산의 일각에 불과합니다. :)
직무:
다음과 같은 XML 파일 "company.xml"이 있습니다.
<?xml version="1.0"?>
<company>
<employee>
<firstname>Tom</firstname>
<lastname>Cruise</lastname>
</employee>
<employee>
<firstname>Paul</firstname>
<lastname>Enderson</lastname>
</employee>
<employee>
<firstname>George</firstname>
<lastname>Bush</lastname>
</employee>
</company>
이 파일을 읽고 모든 직원 의 firstName
및 lastName
필드를 인쇄 해야합니다.
자바 : [ 여기 에서 가져옴 ]
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XmlReader {
public static void main(String[] args) {
try {
File file = new File("company.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
NodeList nodeLst = doc.getElementsByTagName("employee");
for (int s = 0; s < nodeLst.getLength(); s++) {
Node fstNode = nodeLst.item(s);
if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
Element fstElmnt = (Element) fstNode;
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("firstname");
Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
NodeList fstNm = fstNmElmnt.getChildNodes();
System.out.println("First Name: " + ((Node) fstNm.item(0)).getNodeValue());
NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("lastname");
Element lstNmElmnt = (Element) lstNmElmntLst.item(0);
NodeList lstNm = lstNmElmnt.getChildNodes();
System.out.println("Last Name: " + ((Node) lstNm.item(0)).getNodeValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Scala : [ 여기 에서 가져옴 , 슬라이드 # 19]
import xml.XML
object XmlReader {
def main(args: Array[String]): Unit = {
XML.loadFile("company.xml") match {
case <employee> { employees @ _* } </employee> => {
for(e <- employees) {
println("First Name: " + (e \ "firstname").text)
println("Last Name: " + (e \ "lastname").text)
}
}
}
}
}
[빌 편집; 토론에 대한 의견 확인]-
흠, 형식이 지정되지 않은 답장 섹션에 답장하지 않고 수행하는 방법 ... 음. 나는 당신의 대답을 편집하고 그것이 당신을 괴롭히는 경우 삭제하도록 할 것이라고 생각합니다.
이것이 더 나은 라이브러리를 사용하여 Java에서 수행하는 방법입니다.
public scanForEmployees(String filename) {
GoodXMLLib source=new GoodXMLLib(filename);
while( String[] employee: source.scanFor("employee", "firstname", "lastname") )
{
System.out.println("First Name: " + employee[0]);
System.out.println("Last Name: " + employee[1]);
}
}
이것은 마법과 모든 재사용 가능한 구성 요소를 포함하는 빠른 해킹입니다. 마법을 추가하고 싶다면 문자열 배열의 배열을 반환하는 것보다 더 나은 일을 할 수 있지만, 그렇더라도 GoodXMLLib는 완전히 재사용 할 수 있습니다. scanFor의 첫 번째 매개 변수는 섹션이며, 향후 모든 매개 변수는 제한된 항목을 찾을 수 있지만 인터페이스는 약간 버프되어 실제 문제없이 여러 수준의 일치를 추가 할 수 있습니다.
Java는 일반적으로 라이브러리 지원이 매우 열악하다는 것을 인정하지만 Java의 10 년 (?) 오래된 XML 라이브러리의 끔찍한 사용을 간결한 구현을 기반으로 수행 한 구현과 비교하는 것은 공정하지 않습니다. 언어 비교에서!
문자열에 따라 수행 할 작업 맵입니다.
자바 7 :
// strategy pattern = syntactic cruft resulting from lack of closures
public interface Todo {
public void perform();
}
final Map<String, Todo> todos = new HashMap<String,Todo>();
todos.put("hi", new Todo() {
public void perform() {
System.out.println("Good morning!");
}
} );
final Todo todo = todos.get("hi");
if (todo != null)
todo.perform();
else
System.out.println("task not found");
스칼라 :
val todos = Map( "hi" -> { () => println("Good morning!") } )
val defaultFun = () => println("task not found")
todos.getOrElse("hi", defaultFun).apply()
그리고 모든 것이 가능한 최고의 맛으로 이루어집니다!
자바 8 :
Map<String, Runnable> todos = new HashMap<>();
todos.put("hi", () -> System.out.println("Good morning!"));
Runnable defaultFun = () -> System.out.println("task not found");
todos.getOrDefault("hi", defaultFun).run();
todos.get("hi")
반환 Option[()=>Unit]
.
val defaultFun = {() => println("task not found")}; todos.getOrElse("hi", defaultFun).apply()
val todos = Map("hi" -> { () => println("Good morning!") }) withDefaultValue { () => println("task not found") }
그리고 그 다음todos("hi")()
지금 스칼라로 블랙 잭 게임을 작성하고 있습니다. 여기에 내 DeerWins 메서드가 Java에서 어떻게 보이는지가 있습니다.
boolean dealerWins() {
for(Player player : players)
if (player.beats(dealer))
return false;
return true;
}
Scala에서 어떻게 보이는지 다음과 같습니다.
def dealerWins = !(players.exists(_.beats(dealer)))
고차 함수 만세!
Java 8 솔루션 :
boolean dealerWins() {
return players.stream().noneMatch(player -> player.beats(dealer));
}
def dealerWins = !(players exists (_ beats dealer))
David Pollak의 'Beginning Scala'책에서 가져온이 간단한 정렬 및 변환 예제가 마음에 들었습니다.
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)))
자바 :
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)
Quicksort는 어떻습니까?
다음은 Google 검색을 통해 찾은 Java 예제입니다.
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 버전에 대한 빠른 시도. 코드 향상자를위한 오픈 시즌; @)
def qsort(l: List[Int]): List[Int] = {
l match {
case Nil => Nil
case pivot::tail => qsort(tail.filter(_ < pivot)) ::: pivot :: qsort(tail.filter(_ >= pivot))
}
}
partition
그것을 피하기 위해 사용하십시오 .
알 수없는 사용자의 답변이 너무 마음에 들었 습니다. 개선을 위해 노력하겠습니다. 아래 코드는 하지 자바 예제를 직접 번역,하지만 같은 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)
}
나는 mutableMap에서 발견되고 여기에 표시된 getOrElseUpdate 메소드를 많이 좋아합니다.
public static Map <String, Integer> wordCount (Scanner sc, String delimiters) {
Map <String, Integer> dict = new HashMap <String, Integer> ();
while (sc.hasNextLine ()) {
String[] words = sc.nextLine ().split (delimiters);
for (String word: words) {
if (dict.containsKey (word)) {
int count = dict.get (word);
dict.put (word, count + 1);
} else
dict.put (word, 1);
}
}
return dict;
}
예-WordCount, 여기 스칼라 :
def wordCount (sc: Scanner, delimiter: String) = {
val dict = new scala.collection.mutable.HashMap [String, Int]()
while (sc.hasNextLine ()) {
val words = sc.nextLine.split (delimiter)
words.foreach (word =>
dict.update (word, dict.getOrElseUpdate (word, 0) + 1))
}
dict
}
그리고 여기 Java 8에 있습니다.
public static Map<String, Integer> wordCount(Scanner sc, String delimiters)
{
Map<String, Integer> dict = new HashMap<>();
while (sc.hasNextLine())
{
String[] words = sc.nextLine().split(delimiters);
Stream.of(words).forEach(word -> dict.merge(word, 1, Integer::sum));
}
return dict;
}
그리고 100 % 기능을 사용하려면 :
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.*;
public static Map<String, Long> wordCount(Scanner sc, String delimiters)
{
Stream<String> stream = stream(sc.useDelimiter(delimiters));
return stream.collect(groupingBy(identity(), counting()));
}
public static <T> Stream<T> stream(Iterator<T> iterator)
{
Spliterator<T> spliterator = Spliterators.spliteratorUnknownSize(iterator, 0);
return StreamSupport.stream(spliterator, false);
}
filter
그리고 sort
이미 밝혀졌다, 그러나보기는 얼마나 쉽게 그들은지도 통합되어 있습니다 :
def filterKeywords (sc: Scanner, keywords: List[String]) = {
val dict = wordCount (sc, "[^A-Za-z]")
dict.filter (e => keywords.contains (e._1)).toList . sort (_._2 < _._2)
}
이것은 매우 간단한 예입니다. 정사각형 정수를 추가하고
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을 Map으로 전환합니다.
<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)
sumSquare
Scala에서 의 문제 는 Java 개발자에게 매우 비밀 스럽기 때문에 Scala가 모호하고 복잡하다고 불평하는 탄약을 줄 것입니다.
문제 : 주어진 코드를 비동기 적으로 실행할 메서드를 설계해야합니다. 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
}
Michael Nygard의 Release It in FaKods ( link to code ) 의 Circuit Breaker 패턴
Scala에서 구현은 다음과 같습니다.
. . .
addCircuitBreaker("test", CircuitBreakerConfiguration(100,10))
. . .
class Test extends UsingCircuitBreaker {
def myMethodWorkingFine = {
withCircuitBreaker("test") {
. . .
}
}
def myMethodDoingWrong = {
withCircuitBreaker("test") {
require(false,"FUBAR!!!")
}
}
}
정말 좋은 것 같아요. 언어의 그림처럼 보이지만 모든 작업을 수행 하는 CircuitBreaker 개체 의 간단한 믹스 인입니다 .
/**
* 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의 다른 언어 참조.
저는 Scala의 이해하기 쉬운 기능만을 활용하여 Java 및 Scala 코드의 여러 예제를 제공하는 문서를 준비하고 있습니다.
추가를 원하시면 댓글에 답장 해주세요.
이전에 아무도 게시하지 않은 이유 :
자바:
class Hello {
public static void main( String [] args ) {
System.out.println("Hello world");
}
}
116 자
스칼라 :
object Hello extends App {
println("Hello world")
}
56 자
Application
고려 유해 ... 특징 부 (trait) scala-blogs.org/2008/07/...
느리게 평가 된 무한 스트림이 좋은 예입니다.
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는 일급 함수를 지원하지 않으며 익명의 내부 클래스로 클로저를 모방하는 것은 그리 우아하지 않습니다. 이 예제에서 자바가 할 수없는 또 다른 것은 인터프리터 / REPL에서 코드를 실행하는 것입니다. 코드 스 니펫을 빠르게 테스트하는 데 매우 유용합니다.
Iterable
와 Iterator
무한 스트림을 생성 할 수 있습니다.
이 스칼라 코드는 ...
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))
})
}
... 가능하다면 자바에서는 완전히 읽을 수 없습니다.