स्काला और जावा कोड के नमूने जहां स्काला कोड सरल दिखता है / कम लाइनें हैं?


94

मुझे स्काला और जावा कोड के कुछ कोड नमूनों की आवश्यकता है (और मैं भी वास्तव में उनके बारे में उत्सुक हूं) जो बताते हैं कि स्काला कोड अधिक सरल और संक्षिप्त है तो जावा में लिखा कोड (निश्चित रूप से दोनों नमूनों को एक ही समस्या को हल करना चाहिए)।

यदि "स्कैला में यह अमूर्त कारखाना है, तो जावा में टिप्पणी के साथ केवल स्काला नमूना है, यह बहुत अधिक बोझिल दिखाई देगा" तो यह भी स्वीकार्य है।

धन्यवाद!

मुझे सभी स्वीकार किए जाते हैं और यह जवाब पसंद है


3
थोड़े से काम के साथ, आपको rosettacode.org
nicerobot

4
इस तरह के प्रश्न में एक सही उत्तर कैसे हो सकता है?
पॉलीजेन लुब्रिकेंट्स

@ पॉलीऑक्सीज़ेलेब्रिकेंट: और आप क्या सुझाव देते हैं?
रोमन

10
@ रोमन: हम उम्मीद करते हैं कि स्काला अधिक संक्षिप्त होगी। यह अधिक दिलचस्प होगा यदि आप कुछ ऐसा पा सकते हैं जो स्कैला की तुलना में जावा में अधिक स्पष्ट रूप से व्यक्त किया गया था।
रान्डेल शुल्ज

1
@ रैंडल शुल्ज़: हर कोई जानता है कि स्काला अधिक संक्षिप्त है, लेकिन कभी-कभी, शैक्षणिक उद्देश्य में, हमें उदाहरणों और पृष्ठभूमि सिद्धांत के साथ एक प्रमाण की आवश्यकता होती है।
रोमन

जवाबों:


76

आइए स्टेकर के उदाहरण में सुधार करें और स्काला के केस कक्षाओं का उपयोग करें :

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

उपरोक्त स्काला क्लास में नीचे जावा क्लास की सभी विशेषताएं हैं, और कुछ और - उदाहरण के लिए यह पैटर्न मिलान (जो जावा में नहीं है) का समर्थन करता है। स्केल 2.8 में नाम और डिफ़ॉल्ट तर्क जोड़े गए हैं, जिनका उपयोग केस कक्षाओं के लिए एक प्रतिलिपि विधि उत्पन्न करने के लिए किया जाता है , जो निम्न जावा वर्ग के * तरीकों के साथ समान क्षमता देता है।

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)

2
2.7.x और 2.8.0 में केवल मुक्केबाजी में है productElementsऔर unapply: में नहीं निर्माता, क्षेत्र, या एक्सेसर, gist.github.com/424375
retronym

2
सभी प्रकार के गेटटर / सेटर बैज को प्रोत्साहित करता है। सेटर्स को केवल अत्यधिक अनिच्छा के साथ जोड़ा जाना चाहिए, गेट्स को केवल यदि आवश्यक हो तो जोड़ा जाना चाहिए। "सादगी" को जोड़ने का अच्छा उदाहरण बुरी आदतों की ओर जाता है।
बिल के

7
@ बिल के: ठीक है, तो हमारे पास case class Person(val firstName: String, val lastName: String) तो क्या होगा? उस चीज़ को निजी बनाना भी संभव होगा, लेकिन इसका कोई मतलब नहीं है, क्योंकि अनपेक्षित रूप से आदि
सामाजिक

1
@ शिव case class Person(private val firstName: String), लेकिन आपको तब केस क्लासेस का उपयोग नहीं करना चाहिए। इसके बजाय डिफ़ॉल्ट रूप से करना class Person(firstName: String)और firstNameनिजी है।
nilskp

1
@shiva संख्या के बीच का अंतर valऔर private valहै कि क्या एक्सेसर तरीकों, अर्थात् है firstName()और firstName(String), सार्वजनिक या निजी रहे हैं। स्काला के खेतों में हमेशा निजी होते हैं। स्काला के लिए जावा-स्टाइल गेट / सेट मेथड्स (स्काला-स्टाइल एक्सेसर्स के अलावा) उत्पन्न करने के लिए @BeanPropertyएनोटेशन है।
एस्को लुओटोला

45

मुझे यह एक प्रभावशाली लगा

जावा

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एनोटेशन के साथ मापदंडों को एनोटेट करना होगा।
अभिनव सरकार

7
@ abhin4v: हां, लेकिन स्काला में कोड कन्वेंशन के पास उपसर्ग नहीं हैं get। मुहावरेदार जावा कोड मुहावरेदार स्काला कोड से अलग है। कभी-कभी isबूलियन के लिए उपसर्ग का उपयोग किया जाता है। davetron5000.github.com/scala-style/naming_conventions/methods/…
Esko Luontola

6
आप इसे बना सकते हैं case classऔर प्राप्त कर सकते हैं toString, equalsऔर hashCodeमुफ्त में (और आपको तर्क भी valस्पष्ट रूप से नहीं देना है):case class Person(firstName: String, lastName: String)
जेसपर

@ शिव, case classसिर्फ के लिए नहीं class
nilskp

23

कार्य: कीवर्ड की सूची (जैसे किताबें) को अनुक्रमित करने के लिए एक कार्यक्रम लिखें।

स्पष्टीकरण:

  • इनपुट: सूची <स्ट्रिंग>
  • आउटपुट: मानचित्र <चरित्र, सूची <स्ट्रिंग >>
  • मानचित्र की कुंजी 'A' से 'Z' है
  • मानचित्र में प्रत्येक सूची को क्रमबद्ध किया गया है।

जावा:

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

आप (v सॉर्टबी पहचान) के बजाय v.sorted का उपयोग कर सकते हैं।
ईस्टसुन

1
और स्केल 2.8 के साथ, आप नक्शे {केस ...} के बजाय मैपवैल्यूज़ (_.sorted) का उपयोग कर सकते हैं
एलेक्स बिसवर्ट

10
Java 8 के साथ, कोड लगभग Scalas के समान है: keywords.stream ()। सॉर्ट किया गया ()। कलेक्ट करें। (संग्राहक। समूहबद्ध करना (यह -> it.charAt (0))); उसने चाल चली!
समन्वयक

11

कार्य:

आपके पास 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))

अपडेट करें

जब से मैंने यह उत्तर लिखा है, काफी प्रगति हुई है। लैम्ब्डा (और विधि संदर्भ) अंततः जावा में आ गए हैं, और वे तूफान से जावा दुनिया को ले जा रहे हैं।

यह उपरोक्त कोड जावा 8 (@fredoverflow द्वारा योगदान) के साथ कैसा दिखेगा :

people.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));

हालांकि यह कोड लगभग उतना ही छोटा है, यह स्केला एक के रूप में उतने काम नहीं करता है।

स्काला समाधान में, Seq[A]#sortByविधि एक समारोह को स्वीकार करता है A => B, जहां Bके लिए आवश्यक है है एक OrderingOrderingएक प्रकार-वर्ग है। दोनों दुनियाओं में से सबसे अच्छा सोचो: जैसे Comparable, यह प्रश्न में प्रकार के लिए निहित है, लेकिन जैसे Comparator, यह एक्स्टेंसिबल है और इसे पूर्वव्यापी रूप से उन प्रकारों में जोड़ा जा सकता है जिनके पास यह नहीं था। चूँकि जावा में टाइप-क्लास का अभाव है, इसलिए उसे हर एक विधि की नकल करनी पड़ती है, एक बार के Comparableलिए Comparator। उदाहरण के लिए, देखें comparingऔर thenComparing यहां

प्रकार-वर्ग किसी को "अगर A के पास आदेश है और B के पास आदेश है, तो उनके tuple (A, B) का भी आदेश है" जैसे नियम लिखने की अनुमति देता है। कोड में, वह है:

implicit def pairOrdering[A : Ordering, B : Ordering]: Ordering[(A, B)] = // impl

इस sortByतरह हमारे कोड में नाम और फिर उम्र के हिसाब से तुलना की जा सकती है। उन शब्दार्थों को उपरोक्त "नियम" से कूटबद्ध किया जाएगा। एक स्काला प्रोग्रामर सहज रूप से इस तरह से काम करने की उम्मीद करेगा। इसमें कोई विशेष उद्देश्य विधियाँ नहीं comparingजोड़ी जानी थीं Ordering

लैम्ब्डा और विधि संदर्भ एक हिमशैल की एक टिप है जो कार्यात्मक प्रोग्रामिंग है। :)


मिसिंग लैम्बदास (या कम से कम विधि संदर्भ) सबसे महत्वपूर्ण विशेषता है जो मुझे जावा में याद आती है।
पेट्र ग्लैडिख

@fredoverflow Java 8 उदाहरण जोड़ने के लिए धन्यवाद। यह अभी भी दर्शाता है कि स्काला का दृष्टिकोण बेहतर क्यों है। मैं और बाद में जोड़ूंगा।
लापताफैक्टर

@rakemous, दोस्त, जवाब छह साल पहले लिखा गया था।
लापता होने वाला डिकेटर

10

कार्य:

आपको एक 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();
    }
  }
}



स्केल: [ यहाँ से लिया गया , स्लाइड # 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)
        } 
      }
    }
  }
}

[बिल द्वारा संपादित करें; चर्चा के लिए टिप्पणियों की जाँच करें] -

हम्म, यह एक बिना उत्तर अनुभाग में उत्तर के बिना कैसे करें ... Hmph। मुझे लगता है कि मैं आपके उत्तर को संपादित कर दूंगा और आपको इसे बगैर डिलीट कर दूंगा।

यह मैं इसे बेहतर पुस्तकालयों के साथ जावा में कैसे करूंगा:

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 पूरी तरह से पुन: प्रयोज्य होगा। स्कैनफॉर का पहला पैरामीटर सेक्शन है, भविष्य के सभी पैरामीटर आइटम खोजने के लिए होंगे जो सीमित है, लेकिन बिना किसी वास्तविक समस्या के मिलान के कई स्तरों को जोड़ने के लिए इंटरफ़ेस को थोड़ा बफर किया जा सकता है।

मैं मानता हूँ कि जावा में सामान्य रूप से कुछ बहुत खराब पुस्तकालय समर्थन है, लेकिन आते हैं - जावा के दशक के एक भयानक उपयोग की तुलना करने के लिए (?) पुराने एक्सएमएल पुस्तकालय के कार्यान्वयन के आधार पर किए गए कार्य केवल उचित नहीं है - और दूर है भाषाओं की तुलना से!


हम्म, जावा का उदाहरण एसएएक्स या स्टैक्स पार्सर के साथ कम और बेहतर होगा। लेकिन फिर भी SCALA एक वास्तव में अच्छा है
जैतून

5
जावा कोड को उस विशेष XML फ़ाइल को पार्स करने के लिए लिखा गया है, जिसमें पुन: उपयोग और बहुत सारे डुप्लिकेट कोड नहीं हैं। जिसने भी लिखा वह या तो जानबूझकर देखने की कोशिश कर रहा था जैसे वह कोडिंग को नहीं समझता था या कोडिंग को नहीं समझता था।
बिल के

@ बिल के: मैंने कभी भी जावा में XML पार्सिंग नहीं की है इसलिए मैंने कुछ बेतरतीब साइट से इस उदाहरण को चुना है। जवाब के जावा भाग को संपादित करने के लिए स्वतंत्र महसूस करें, मुझे कोई आपत्ति नहीं है।
गुमशुदा

ठीक है, मान लें कि आप भाषा के अंतर की बात कर रहे हैं न कि पुस्तकालय के अंतर की - उस मामले में, दोनों लगभग समान होंगे। दूसरे उदाहरण में केवल भाषा का अंतर मैच / केस की चीज है जो कि लूप के रूप में एक लाइन में किया जा सकता है अगर लाइब्रेरी द्वारा उस तरह से लागू किया जाता है।
बिल के।

@ बिल के: नहीं, आप पूरी तरह से गलत हैं। यहां काम पर दो बहुत शक्तिशाली स्काला विशेषताएं हैं: 1. एक्सएमएल साहित्य 2. पैटर्न मिलान। जावा के पास इनमें से कुछ भी नहीं है। तो कुछ काल्पनिक पुस्तकालय में लिखे गए बराबर जावा कोड निश्चित रूप से समान नहीं होंगे। (लिखने की कोशिश करो, तुम्हें पता चल जाएगा।)
लापता

10

एक स्ट्रिंग के आधार पर प्रदर्शन करने के लिए क्रियाओं का मानचित्र।

जावा 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]जो ठीक से मैच करने के लिए आवश्यक है।
13 अक्टूबर को हुन्हज्ल

@huynhjl, मेरा बुरा। इसे वापस ले लिया।
लापताफटोर

3
और भी छोटा हो सकता है:val defaultFun = {() => println("task not found")}; todos.getOrElse("hi", defaultFun).apply()
ज्योफ रेनी

2
इससे भी छोटा: val todos = Map("hi" -> { () => println("Good morning!") }) withDefaultValue { () => println("task not found") }और फिरtodos("hi")()
मार्टिन रिंग

8

मैं अब स्काला में एक ब्लैकजैक गेम लिख रहा हूं। यहाँ मेरा डीलरविन्स विधि जावा में कैसा दिखेगा:

boolean dealerWins() {
    for(Player player : players)
        if (player.beats(dealer))
            return false;
    return true;
}

यहां देखें कि यह स्काला में कैसा दिखता है:

def dealerWins = !(players.exists(_.beats(dealer)))

उच्च-आदेश कार्यों के लिए हुर्रे!

जावा 8 समाधान:

boolean dealerWins() {
    return players.stream().noneMatch(player -> player.beats(dealer));
}

scala में बहुत मुश्किल सिंटैक्स होता है। इतना याद रखने की जरूरत है :-(
AZ_

स्काला सीएसएस की तरह है, याद रखने के लिए कई विशेषताओं और गुणों में
AZ_

1
बेहतर:def dealerWins = !(players exists (_ beats dealer))
केविन राइट

7

मुझे डेविड पोलाक की 'बिगनिंग स्काला' पुस्तक से लिया गया छँटाई और परिवर्तन का यह सरल उदाहरण पसंद आया:

स्काला में:

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)

6

क्विकॉर्ट के बारे में कैसे?


जावा

निम्नलिखित एक जावा उदाहरण है जो एक Google खोज के माध्यम से मिलता है,

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
}

स्काला

एक स्काला संस्करण में एक त्वरित प्रयास। कोड कामचलाऊ के लिए खुला मौसम; @)

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

1
लिंक की गई सूचियों पर उस क्विकॉर्ट में O (n ^ 2) समय की जटिलता है या नहीं? आमतौर पर मर्जर्ट्स या समान का उपयोग लिंक्ड सूचियों के लिए किया जाता है।
एस्को लुओंटोला

3
यह पुनरावर्ती भी नहीं है और इसलिए एक
परफॉर्मर

उपयोगी टिप्पणियों के लिए धन्यवाद। मैंने देखा था कि क्विकसॉर्ट को इस तरह लिखा गया था और यह कॉम्पैक्टनेस से प्रभावित था, स्पष्ट रूप से मैंने इसे बहुत अधिक विचार नहीं दिया था। मैं LOC तुलना से दूर हो गया, जो हमेशा Scala v Java के साथ एक मोहक चीज़ है।
डॉन मैकेंजी

2
Quicksort कार्यात्मक सूचियों पर O (n ^ 2) नहीं है , लेकिन इसमें निश्चित रूप से वह खतरा है। Asymptotically, यह अभी भी O (n लॉग एन) औसत है , लेकिन सबसे खराब स्थिति O (n ^ 2) से टकराने की एक उच्च सांख्यिकीय संभावना है क्योंकि हम हमेशा यादृच्छिक के बजाय एक को चुनने के बजाय सूची के शीर्ष पर धुरी बिंदु का चयन करते हैं। ।
डैनियल स्पिवक

दो बार छानना बुरा है। अपने प्रश्न के उत्तर में देखें partitionकि इससे बचने का उपयोग ।
डैनियल सी। सोबरल

6

मुझे उपयोगकर्ता का अज्ञात जवाब पसंद आया, इसलिए मैं उस पर सुधार करने की कोशिश करने जा रहा हूं। नीचे दिया गया कोड जावा उदाहरण का सीधा अनुवाद नहीं है, लेकिन यह समान एपीआई के साथ समान कार्य को पूरा करता है।

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

मेरे पास इस स्निपेट का परीक्षण करने के लिए अब तक scala-2.8 स्थापित नहीं है, लेकिन मुझे लगता है कि मैं देख सकता हूं कि क्या इरादा है - बस 'कीवर्ड' का उपयोग नहीं किया जाता है। यह सभी स्ट्रिंग्स और उनकी आवृत्तियों का एक मानचित्र तैयार करता है, है ना?
उपयोगकर्ता अज्ञात

@user हाँ, यह वही करता है। ऐसा नहीं है कि आपके कोड द्वारा क्या पूरा किया गया है? ओह मैं समझा। मैंने गलत लाइन कॉपी की। मैं इसे अभी ठीक करने जा रहा हूँ। :-)
डैनियल सी। सोबरल

6

मुझे बहुत पसंद है विधि getOrElseUpdate, mutableMap में पाया जाता है और यहां दिखाया गया है, पहले जावा, बिना:

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, और यहाँ scala में:

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
}

और यहाँ यह जावा 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)
    } 

मुझे यह उदाहरण बहुत पसंद है। यह केस कक्षाओं की तुलना करने के आसान मार्ग से बचता है, और स्कैला कोड दिखाने की गलती नहीं करता है और न ही जावा समकक्ष।
डेनियल सी। सोबरल

5

यह एक बहुत ही सरल उदाहरण है: स्क्वायर पूर्णांक और फिर उन्हें जोड़ें


    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 )

यह मैं जावा में (बहुत काम करने के लिए) कोशिश नहीं करूंगा, 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)

sumSquareस्काला में आपके साथ समस्या यह है कि यह एक जावा डेवलपर के लिए बहुत ही गूढ़ है, जो उन्हें आपके खिलाफ बार-बार शिकायत करेगा कि स्काला अस्पष्ट और जटिल है ...
जेसपर

मैंने उदाहरण को बेहतर बनाने के लिए थोड़ा सुधार किया। आशा है कि यह स्काला को नुकसान नहीं पहुंचाएगा।
थॉमस

5
scala> 1 से 10 नक्शा (x => x * x) योग res0: Int = 385 आइए जावा डेवलपर कॉल को देखें जो कि गुप्त है। उस बिंदु पर यह कानों में उँगलियाँ कह रहा है कि नाह-न-नाह।
PSP

3
@ जैस्पर एक गैर-जावा डेवलपर के लिए, जावा भारी मात्रा में बॉयलरप्लेट और लाइन शोर की तरह दिखता है। इसका मतलब यह नहीं है कि आप भाषा में वास्तविक काम नहीं कर सकते।
जेम्स मूर

आप foldLeft (0) (add) के बजाय कम लिफ़्ट (ऐड) का उपयोग कर सकते हैं। मुझे लगता है कि जब आपका प्रारंभ तत्व समूह का शून्य / पहचान तत्व है, तो पढ़ना आसान है।
डेबिल्स्की

5

समस्या: आपको एक विधि डिजाइन करने की आवश्यकता है जो किसी भी कोड को अतुल्यकालिक रूप से निष्पादित करेगी। जावा

में समाधान :

/**
* 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
            }
});

स्काला में यही बात (अभिनेताओं का उपयोग करते हुए):

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    
}

6
2.8 के रूप में, इसे फ्यूचर्स.फुटेन {बॉडी} के रूप में लिखा जा सकता है और वास्तव में अधिक शक्तिशाली है क्योंकि इसके द्वारा लौटाए गए भविष्य को उस मूल्य में शामिल होने के लिए जोड़ा जा सकता है जिसका वह अंततः मूल्यांकन करता है।
डेव ग्रिफ़िथ

3

माइकल Nygard की यह Faqods में रिलीज से सर्किट ब्रेकर पैटर्न ( लिंक करने के लिए लिंक )

कार्यान्वयन स्कला में इस तरह दिखता है:

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


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

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

जो मुझे लगता है कि सुपर अच्छा है। यह सिर्फ भाषा के एक टुकड़े के रूप में दिखता है, लेकिन यह सर्किटब्रीकर ऑब्जेक्ट में एक सरल मिश्रण है जो सभी काम कर रहा है।

/**
 * 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।


3

मैं एक दस्तावेज तैयार कर रहा हूं जो जावा और स्काला कोड के कई उदाहरण देता है, जो केवल स्काला की विशेषताओं को समझने के लिए सरल का उपयोग करता है:

स्काला: एक बेहतर जावा

यदि आप मुझे इसके साथ कुछ जोड़ना चाहते हैं, तो कृपया टिप्पणियों में उत्तर दें।


शीर्षक "स्काला: एक बेहतर जावा"
मिसलीडिंग है

2

इससे पहले किसी ने क्यों पोस्ट नहीं किया:

जावा:

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

116 अक्षर।

स्काला:

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

56 वर्ण।


1
Applicationहानिकारक माना जाता है ... scala-blogs.org/2008/07/…
अक्टूबर को ak10 में अनुपलब्ध

1

लज़ीज़ मूल्यांकित अनंत धाराएँ एक अच्छा उदाहरण हैं:

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

}

यहां जावा में अनंत धाराओं को संबोधित करने वाला एक प्रश्न है: क्या एक अनंत पुनरावृत्त खराब डिजाइन है?

एक और अच्छा उदाहरण प्रथम श्रेणी के कार्य और क्लोजर हैं:

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)

जावा प्रथम श्रेणी के कार्यों का समर्थन नहीं करता है, और अनाम आंतरिक कक्षाओं के साथ निकटता की नकल करना बहुत सुरुचिपूर्ण नहीं है। एक और बात इस उदाहरण से पता चलता है कि जावा एक इंटरप्रेटर / REPL से कोड नहीं चला रहा है। मुझे कोड स्निपेट के परीक्षण के लिए यह बेहद उपयोगी लगता है।


कृपया ध्यान दें कि छलनी व्यावहारिक होने के लिए बहुत धीमी है।
एलजार लीबोविच

@oxbow_lakes इन उदाहरणों के लिए कोई समान जावा नहीं है।
dbyrne

@dbyme सच नहीं है। आप जावा की आसानी से Iterableऔर Iteratorअनंत धाराओं का निर्माण कर सकते हैं ।
डैनियल सी। सोबरल

@dbyrne "एक और बात इस उदाहरण से पता चलता है कि जावा ऐसा नहीं कर सकता है एक दुभाषिया / REPL से कोड चला रहा है। मुझे यह जल्दी से कोड स्निपेट के परीक्षण के लिए बेहद उपयोगी लगता है।" मैं जावा स्निपेट्स को आज़माने के लिए एक्लिप्स में एक स्क्रैपबुक पेज का उपयोग करता हूं। सबसे ज्यादा अगर सभी ID उस IDE में काम नहीं करते हैं, तो मुझे कोई REPL की आवश्यकता नहीं है। मैंने अपने शुरुआती दिनों में notepad.exe और javac का उपयोग किया जब मैं किसी भाषा या लाइब्रेरी सुविधा के बारे में अनिश्चित था और थोड़े समय के बाद जो बहुत अच्छी तरह से और तेजी से चला गया - हालांकि एक REPL उपयोग करने के लिए कुछ आसान है - और तेज़। मैं विजुअलएज को स्थापित करके नोटपैड हैक से पूरी तरह बच सकता था, जो हमारे पास पहले से ही था

0

यह स्काला कोड ...

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

... यदि संभव हो तो जावा में पूरी तरह से अपठनीय होगा।


10
मेरा सही OPINIO: उत्तर के लिए धन्यवाद! लेकिन क्या आप कृपया बता सकते हैं कि वहाँ क्या होता है? मैं अभी तक स्काला सिंटैक्स से परिचित नहीं हूं, और (संभव यही कारण है कि) यह मेरे लिए अब भी पूरी तरह से अपठनीय लगता है।
रोमन

यह केस स्टेटमेंट के पैटर्न मैचिंग क्लॉज में एक गार्ड के रूप में एक दिए गए पार्टीशनिंग फंक्शन का उपयोग करके टाइप T की एक सामान्य सूची का विभाजन कर रहा है।
सिर्फ मेरा सही जनन

3
अजीब। मैं दूर से एक स्काला विशेषज्ञ भी नहीं हूँ और यह पता लगा सकता हूँ।
JUST MY सही ओपिनियन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.