Las muestras de la Scala y el código de Java donde Scala código es más simple/tiene menos líneas?

Necesito algunos ejemplos de código (y yo también muy curioso acerca de ellos) de la Scala y de código Java que muestran que la Scala código es más simple y concisa, a continuación, el código escrito en Java (por supuesto, ambas muestras debe resolver el mismo problema).

Si sólo hay Scala ejemplo, con comentarios como «este es el resumen de la fábrica en la Scala, en Java se verá mucho más complicado», entonces esto también es aceptable.

Gracias!

Que más me gusta de todos aceptaron y este respuestas

  • Con un poco de la pierna de trabajo, usted puede encontrar un montón de muestras en rosettacode.org
  • ¿Cómo puede haber una respuesta correcta en este tipo de pregunta?
  • y lo que usted sugiere?
  • Dónde está el cw de la policía cuando sea necesario?
  • ustedes dicen, » subjetiva y discutible,’ como si fuera algo malo. por cierto, es subjetivo, pero no argumentativo.
  • Reyes: yo en realidad no creo que esta pregunta es un comminity wiki. No hay ningún corresponsal tipo de preguntas en LO que se ahora. Es una pregunta habitual, pero con múltiples respuestas correctas. Actualmente veo al menos 2 respuestas correctas. Incluso si me marca una pregunta como cw no voy a ser capaz de marcar los 2 respuestas. Así, la policía no tiene nada que hacer aquí.
  • Esperamos Scala para ser más conciso. Sería más interesante si se pudiera encontrar algo que era más sucintamente expresado en Java que en Scala.
  • Schulz: todo el mundo sabe que Scala es más concisa, pero a veces, en el ámbito académico propósito, necesitamos una prueba con ejemplos y antecedentes de la teoría.
  • El MODO de FAQ dice «que Evite hacer preguntas que son subjetivas, argumentativo, o que requieren discusión extendida.» No es que dice «o» en lugar de «y». El cuadro de cierre de la descripción subjetiva y argumentativa» también afirma que «Es imposible objetivamente responder a esta pregunta; las preguntas de este tipo son demasiado abierto y por lo general conducen a la confrontación y la discusión». (el énfasis es mío)
  • Bemrose: nada es pefrect. Y ASÍ que las reglas sólo confirmar este estado. Subjetiva y discutible, es una pregunta como «¿qué es mejor, java o C#?». Esta pregunta implica la discusión y diferentes, pero no controvertidas opiniones. Tiene ASÍ la posibilidad de hablar de demasiado abiertas preguntas y que definitivamente debería ser usado, pero esta cuestión no es el uno. Definitivamente hay un número final de pretty-buscando respuestas correctas existen, yo thinkg de unos 10 o incluso menos.

InformationsquelleAutor Roman | 2010-06-01

18 Kommentare

  1. 75

    Vamos a mejorar apilador ejemplo y el uso de Scala el caso de las clases:

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

    La Scala clase contiene todas las características de la siguiente clase de Java, y algunos más – por ejemplo soporta la coincidencia de patrón (que Java no tiene). Scala 2.8 añade nombre y argumentos predeterminados, que se utilizan para generar una el método de copia para el caso de las clases, que da la misma capacidad como la con* los métodos de la siguiente clase Java.

    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 + ")";
        }
    }

    Luego, en el uso que se tiene (por supuesto):

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

    Contra

    val mr = Person("Bob", "Dobbelina")
    val miss = Person("Roberta", "MacSweeney")
    val mrs = miss copy (lastName = mr.lastName)
    • Usted tiene que ser cuidadoso caso de las clases heredan de Product y por lo tanto primitivas serán empacados (en scala 2.7) o probablemente-en caja (2.8 uso de especialización)
    • En 2.7.x y 2.8.0 la única boxeo es en productElements y unapply, no en el constructor, de campo, o de los descriptores: gist.github.com/424375
    • Anima a todo tipo de captador/definidor de la maldad. Incubadoras deben ser añadidas con extrema resistencia, los captadores debe ser añadido si es necesario. Buen ejemplo de cómo la adición de la «Simplicidad» conduce a malos hábitos.
    • K: OK, entonces vamos a tener case class Person(val firstName: String, val lastName: String) Entonces, ¿qué? Hacer que cosa privada sería posible también, pero no tiene ningún sentido, porque de deshacer etc.
    • Cómo hacer que el firstName and lastName en la Scala como Privado ?
    • Persona de clase(privado val nombre: String), pero no debe ser con el caso de las clases de entonces. En lugar de hacer class Person(firstName: String) y firstName es privada por defecto.
    • se scala generar obtener:* métodos de si defino firstName and lastName como privada ?
    • No. La diferencia entre val y private val es que si el descriptor de acceso a los métodos, es decir, firstName() y firstName(String), sea pública o privada. En Scala campos son siempre privadas. Para Scala para generar Java-estilo de métodos get/set (además de la Scala de estilo descriptores de acceso), no es el @BeanProperty anotación.
    • también tenga en cuenta que scala clases son inmutables por defecto. Si se mira atentamente, verá que la Persona NO tiene ningún set-sólo los captadores y copia (que produce una nueva persona).
    • Mi verdadero problema es … ¿por Qué hemos de definir un objeto con propiedades cuando nunca hacemos nada con ellos en el código? Si los objetos de trabajo es simplemente para viajar de una interfaz gráfica de usuario a la base de datos, tener un objeto con las propiedades que SÓLO puede agregar código (Si se piensa en ello, la ÚNICA información que NECESITA para obtener un «nombre» de una interfaz gráfica de usuario del formulario a la base de datos es el nombre del campo en el formulario y la tabla/nombre de campo en la DB (y tal vez el nombre de un validador), cero código!–cualquier código de tocar una propiedad específica es repetitivo. Se pueden resolver mediante la anotación de un simple objeto de datos, pero entonces usted no necesita captadores.
    • Si usted no permitir setters y getters que obligaría a escribir el código mejor, el acceso a pura datos como los datos (a través de programación como campos basados en datos rarther de hacerlo directamente a través redundantes, sin sentido copy&paste de código). También en el «Real» de las clases con los miembros que necesitan ser manipulados tendría que hacerlo desde dentro de la propia clase (donde se accede a) en lugar de en el código externo que necesita para Obtener los datos. (Lo siento por el comentario de restricción de longitud, pero no sé dónde más poner este–¿ ASÍ que tienen un vinculables «Wiki» o un blog para la publicación de más respuestas/conceptos)?

  2. 45

    Me pareció un impresionante

    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í como estas (lo siento por no pegar, no me quieren robar el código)

    • Este scala código no generará getFirstName y getLastName métodos. Usted tiene que anotar los parámetros con scala.reflect.BeanProperty anotación para hacer eso.
    • Sí, pero el código de la convención en la Scala es que no tienen los descriptores de acceso con el prefijo get. Idiomáticas código Java es diferente de la idiomáticas Scala código. A veces la is prefijo utilizado para los booleanos. davetron5000.github.com/scala-style/naming_conventions/methods/…
    • Usted podría hacer que un case class y obtener la toString, equals y hashCode de forma gratuita (y usted también no tiene que hacer los argumentos val explícitamente): case class Person(firstName: String, lastName: String)
    • Pero el firstname and lastname en Scala es de derecho Público ?
    • para case class, no sólo para class.
  3. 23

    Tarea: Escribir un programa para el índice de una lista de palabras clave (como los libros).

    Explicación:

    • De entrada: Lista de<Cadena>
    • De salida: Mapa<Carácter, la Lista de<Cadena>>
    • La clave de mapa es la ‘a’ a la ‘Z’
    • Cada lista en el mapa están ordenados.

    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)
    }
    • Usted puede utilizar v. ordenados en lugar de (v sortBy de identidad).
    • Y con Scala 2.8, se puede utilizar mapValues (_.clasificado) en lugar de mapa { case … }
    • Con Java 8, el código es casi idéntico a la Scala: palabras clave.(flujo).ordenada().recoger(Coleccionistas.groupingBy(es -> es.charAt(0))); hace el truco!
  4. 11

    Tarea:

    Usted tiene una lista de people de objetos de la clase Person que tiene campos name y age. Su tarea es ordenar esta lista, primero por name, y luego por age.

    Java 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());
      }
    });

    Scala:

    val sortedPeople = people.sortBy(p => (p.name, p.age))

    Actualización

    Desde que escribí esta respuesta, ha habido algunos progresos. Las funciones lambda (y el método de referencia)han aterrizado en Java, y se están tomando el mundo de Java por la tormenta.

    Esto es lo que el código se verá así con Java 8 (aportado por @fredoverflow):

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

    Aunque este código es casi tan corto, no funciona tan elegantemente como la Scala uno.

    En la Scala de solución, la Seq[A]#sortBy método acepta una función A => B donde B es necesario para han un Ordering. Ordering es un tipo de clase. Creo que lo mejor de ambos mundos: Como Comparable, es implícito para el tipo en cuestión, pero como Comparator, es extensible y puede ser añadido de forma retrospectiva a los tipos que no tienen. Desde Java carece de tipo de clases, tiene que duplicar cada método, de una vez por Comparable, entonces para Comparator. Por ejemplo, ver comparing y thenComparing aquí.

    El tipo de clases que permiten escribir las reglas como «Si ha de ordenar y B ha pedido, a continuación, sus tupla (a, B) también ha pedido». En el código, que es:

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

    Que es como el sortBy en nuestro código se puede comparar por su nombre y, a continuación, por la edad. Los semántica será codificado con los de arriba «regla». En Scala programador intuitivamente esperar que esto funcione de esta manera. Ningún propósito especial de métodos como la comparing tenía que ser añadido a Ordering.

    Lambdas y método de las referencias son sólo la punta de un iceberg que es la programación funcional. 🙂

    • Falta de lambdas (o, al menos, el método de referencia) es la característica más importante que me pierda en Java.
    • Gracias por agregar el Java 8 ejemplo. Todavía demuestra por qué Scala enfoque es superior. Voy a añadir más tarde.
    • el mate, la respuesta fue escrito hace más de seis años.
  5. 10

    Tarea:

    Usted tiene un archivo XML «company.xml» que se parece a esto:

    <?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>

    Tienes que leer este archivo y de impresión de la firstName y lastName los campos de todos los empleados.


    Java: [ tomado de aquí ]

    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: [ tomado de aquí, diapositiva #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)
            } 
          }
        }
      }
    }

    [ EDITAR por Bill; ver los comentarios para el debate ] —

    Hmm, ¿cómo hacerlo sin responder en un formato de respuesta de la sección de… Hmph. Creo que voy a editar tu respuesta y permiten eliminar si se bugs usted.

    Esto es lo que yo haría en Java con la mejor de las bibliotecas:

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

    Esto es sólo un truco rápido que no implica la magia y todos los componentes reutilizables. Si quería añadir un poco de magia podía hacer algo mejor que devuelve una matriz de las matrices de cadena, pero incluso como es este GoodXMLLib sería completamente reutilizable. El primer parámetro de scanFor es la sección, en el futuro todos los parámetros serían los elementos para encontrar lo que es limitado, pero la interfaz podría ser frotado ligeramente para añadir varios niveles de concordancia con un problema real.

    Tengo que admitir que Java tiene algunos bastante buenos soporte de la biblioteca en general, pero vamos, para comparar un horrible el uso de Java década de los años(?) antigua librería XML para una implementación hecho basado en ser conciso es justo no es justo-y está lejos de una comparación de los idiomas!

    • hmm, el ejemplo en Java sería más corto y de mejor apariencia con un SAXO o StAX analizador. Pero todavía la SCALA es realmente agradable
    • El código Java se escribe exactamente a analizar ese particular archivo XML con ningún intento de reutilizar y una gran cantidad de código duplicado. El que lo escribió estaba tratando deliberadamente mirar como él no entendía de codificación o no entender la codificación.
    • K: nunca he hecho el análisis de XML en Java, por eso escogí este ejemplo de algún sitio aleatorio. Siéntase libre de editar el Java parte de la respuesta, no me importa.
    • Bueno, vamos a suponer que usted está hablando de las diferencias de idioma y no de la biblioteca de diferencias-en ese caso, los dos sería casi idéntica. La única diferencia de idioma en el segundo ejemplo es el partido/el caso de lo que se podría hacer en una sola línea como un bucle for, si se implementan de esa manera por la biblioteca.
    • K: No, está completamente equivocado. Hay dos muy potente Scala cuenta en el trabajo: 1. XML Literales 2. La Coincidencia De Patrones. Java no tiene cualquiera de estos. Por lo que el equivalente de Java de código escrito en algún hipotético biblioteca de seguro de NO ser idénticas. (Trate de escribir, vas a saber).
    • K: Por cierto, coincide caso es como un interruptor caso poner en esteroides. Se utiliza para la toma de decisiones, no de bucle.
    • G Actualizado su respuesta para que yo pudiera conseguir el formato del texto. Debo admitir que la coincidencia de patrón PODRÍA ser más potente, pero no estaba siendo utilizado, en este caso, incluso si se podría coincidir con una inteligente formado biblioteca para la mayor parte, utilizando anidada partido declaraciones y expresiones regulares. Para mí el mayor carga en lenguas es la sintaxis–al menos únicos operadores que forman parte de un idioma, más fácil es aprender y comprender en su totalidad. Caso en punto, un montón de sintaxis se añadió a esta Scala solución para ninguna reducción en el tamaño del código–¿por qué?
    • K: Esa es una pregunta muy amplia y te sugiero que publiques como una cuestión separada si usted está realmente interesado en saber la respuesta. Hay gente en este foro que puede contestar mejor que yo.
    • su hipotético código está roto. ¿Cómo te imaginas el scanFor a trabajar, mientras que ser reutilizable al mismo tiempo (es decir, no sólo trabajar para esta particulares caso de uso)? Scala tiene el borde porque no no utilizar cualquier especializados funciones o métodos de aquí, simplemente Scala. Concedido, XPath (o selectores CSS) puede hacer el anterior código Java por tanto más fácil, pero en ninguna parte cerca tan elegante como su hipotético código, y XPath es tan bueno como se pone.
    • Rudolph se necesita un filtro que muestra una sección para buscar en, exploraciones de los elementos en esa sección, crea un iterador o una matriz de matrices de cadena y devuelve. Después de ser devuelto, el iterador/matriz es iterado por el bucle for que devuelve una matriz de cadenas con cada entrada del array [0] o [1] corresponde a uno de los términos de búsqueda. Términos de búsqueda adicionales haría que el tiempo de regresar de la matriz de la variable de argumentos. Podría ser más genérico, permitiendo a los niveles adicionales de filtrado, pero esto más que soluciona el problema existente en una forma que es muy reutilizable. Lo que crees que no funciona?
    • Para hacerlo más genérico, trate de sintaxis, tales como: origen.filter() .inGroup (la»compañía», «Mi Empresa») .inGroup(«empleado») .getFields( «nombre», «apellidos»); Que podría reunir a todos los empleados de «Mi Empresa» y el retorno de sus nombres. No estoy diciendo que este es el mismo que el de la Scala de solución, sé Scala hace parte de esto en el lenguaje -, pero no resuelve el mismo problema, y ese fue mi punto… que esta particular solución de Java era pobre.

  6. 9

    Un mapa de acciones a realizar en función de una cadena.

    Java 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");

    Scala:

    val todos = Map( "hi" -> { () => println("Good morning!") } )
    val defaultFun = () => println("task not found")
    todos.getOrElse("hi", defaultFun).apply()

    Y todo se hace con el mejor gusto posible!

    Java 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();
    • G, creo que su edición es incorrecta. todos.get("hi") devuelve Option[()=>Unit] que es necesario para que coincida correctamente.
    • Mi mal. Rodar de nuevo.
    • Puede ser incluso más corto: val defaultFun = {() => println("task not found")}; todos.getOrElse("hi", defaultFun).apply()
    • impresionante, gracias a Geoff. La adición de su sugerencia.
    • Aún más corto: val todos = Map("hi" -> { () => println("Good morning!") }) withDefaultValue { () => println("task not found") } y, a continuación, todos("hi")()
  7. 7

    Me gustó este simple ejemplo de clasificación y transformación, tomado de David Pollak del Principio de Scala’ libro:

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

    En 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)
  8. 7

    Estoy escribiendo un juego de Blackjack en Scala ahora. Aquí es cómo mi dealerWins método sería en Java:

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

    Aquí es como se ve en la Scala:

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

    ¡Hurra por funciones de orden superior!

    Java 8 solución:

    boolean dealerWins() {
        return players.stream().noneMatch(player -> player.beats(dealer));
    }
    • scala tiene muy difícil de sintaxis. necesidad de recordar mucho 🙁
    • Scala es como el CSS, para muchos de los atributos y propiedades de recordar
    • mejor: def dealerWins = !(players exists (_ beats dealer))
  9. 6

    ¿Quicksort?


    Java

    El siguiente es un ejemplo en java que se encuentra a través de una búsqueda en google,

    la URL es 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

    Un rápido intento de Scala versión. Temporada abierta para el código de enmiendas ;@)

    def qsort(l: List[Int]): List[Int] = {
      l match {
        case Nil         => Nil
        case pivot::tail => qsort(tail.filter(_ < pivot)) ::: pivot :: qsort(tail.filter(_ >= pivot))
      }
    }
    • ¿Que quicksort en las listas enlazadas tienen O(n^2) tiempo de la complejidad o no? Generalmente mergesort o similar se utiliza para listas enlazadas.
    • También no recursiva de cola y, por tanto, inadecuado como un potente algoritmo (o uno que no desbordamiento de la pila)
    • Gracias por los comentarios útiles. Yo había visto quicksort escrito como esta en algún lugar y quedó impresionado por su compacidad, claramente yo no le dan mucha consideración. Me dejó llevar por la LOC de comparación, que es siempre un seductor cosa con Scala v de Java.
    • Quicksort es no O(n^2) funcional de las listas, pero sin duda tiene ese peligro. Asintóticamente, es todavía promedio de O(n log n), pero hay una mayor probabilidad estadística de acertar el peor de los casos O(n^2) porque siempre tenemos que seleccionar el punto de pivote a la cabeza de la lista, en lugar de elegir uno al azar.
    • Filtrado dos veces es malo. Ver en mi respuesta a su pregunta en el uso de partition para evitar que.
  10. 6

    Me gustó usuario desconocido del respuesta tanto voy a tratar de mejorarlo. El código siguiente es no una traducción directa del ejemplo en Java, pero se lleva a cabo la misma tarea con la misma 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)
    }
    • No tengo scala-2.8 instalado por ahora, para probar este fragmento, pero supongo que puedo ver lo que hay intendet – sólo ‘palabras clave’ no se usa en absoluto. Se produce un mapa de todas las Cadenas y sus frecuencias, ¿no?
    • Sí, eso es lo que hace. No es que lo logrado por el código? Oh, ya veo. He copiado la línea incorrecta. Voy a corregirlo ahora mismo. 🙂
  11. 6

    Me gusta mucho el método getOrElseUpdate, se encuentra en mutableMap y aquí se muestra, la primera de Java, sin:

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

    sí – un conteo de palabras, y aquí en 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
    }

    Y aquí es en 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;
    }

    Y si quieres ir 100% funcional:

    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 y sort ya han demostrado, pero mira lo fácil que se integran con el mapa:

        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)
        } 
    • Me gusta este ejemplo mucho. Evita la ruta fácil de comparar el caso de las clases, y no cometer el error de mostrar Scala código y no el de Java equivalente.
  12. 5

    Este es un ejemplo muy simple: la Plaza de los números enteros y, a continuación, agregarlos

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

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

    Mapa compacto aplica la función a todos los elementos de la matriz, así:

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

    Doblar a la izquierda se va a iniciar con 0 como el acumulador (s) y aplicar add(s,i) a todos los elementos (i) de la matriz, de modo que:

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

    Ahora esto puede ser aún más compacta:

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

    Este no voy a tratar en Java (mucho trabajo), convertir XML a un Mapa:

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

    Otro revestimiento para obtener el mapa de el 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)
    • El problema con su sumSquare en la Scala es que se ve muy difíciles de descifrar para un desarrollador de Java, lo que les dará munición contra los que se quejan de que la Scala es oscuro y complicado…
    • Yo formatear un poco a mejorar el ejemplo. Espero que esto no hace daño Scala.
    • scala> 1 a 10 mapa (x => x*x) suma res0: Int = 385 Vamos a ver el desarrollador de java llamada que críptica. En ese punto es dedos en los oídos diciendo: nah-nah-nah.
    • A un no-desarrollador Java, Java se parece a vastas cantidades de repetitivo y ruido en la línea. Eso no significa que usted no puede conseguir el verdadero trabajo que se realiza en el idioma.
    • Usted podría utilizar reduceLeft(agregar) en lugar de foldLeft(0)(agregar). Creo que es más fácil de leer cuando el elemento inicial es el grupo cero/elemento de identidad.
    • Estoy de acuerdo, pero si usted quiere convencer a los desarrolladores de Java que Scala es mejor (como es probablemente el caso con el cartel de la pregunta) entonces podría ser mejor no empezar con algo que puede asustar…
    • El Javacode no es justo, ya que no utiliza la simplificación del bucle for: for(int i : list.length) sum += i*i;.

  13. 5

    Problema: que usted necesita para diseñar un método que se va a ejecutar cualquier código de forma asincrónica.

    Solución en 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
                }
    });

    La misma cosa en Scala (con actores):

    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    
    }
    • 2.8, esto puede ser escrito como Futuros.futuro{cuerpo} y en realidad es más poderosa desde el futuro devuelto por esto se pueden unir para obtener el valor que finalmente se evalúa.
  14. 3

    El Interruptor de Circuito patrón de Michael Nygard del liberarlo en FaKods
    (enlace a código)

    aplicación se ve como esta en la Scala:

    . . .
    addCircuitBreaker("test", CircuitBreakerConfiguration(100,10))
    . . .
    
    
    class Test extends UsingCircuitBreaker {
      def myMethodWorkingFine = {
        withCircuitBreaker("test") {
          . . .
        }
      }
    
      def myMethodDoingWrong = {
        withCircuitBreaker("test") {
          require(false,"FUBAR!!!")
        }
      }
    }

    Que creo que es super agradable. Se ve como un pice de la lengua, sino que es un simple mixin en el Interruptor De Potencia Objeto haciendo todo el trabajo.

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

    De referencia en otros idiomas de Google para «disyuntor» + tu idioma.

  15. 2

    ¿Por qué nadie ha publicado esto antes:

    Java:

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

    116 caracteres.

    Scala:

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

    56 caracteres.

  16. 2

    Estoy preparando un documento que da varios ejemplos de Java y Scala de código, utilizando sólo la simple comprender las características de la Scala:

    Scala : Una mejor Java

    Si que me gustaría agregar algo, por favor, responda en los comentarios.

    • Título de la «Scala: Una mejor Java» es missleading
  17. 1

    Perezosamente evaluado infinitos arroyos son un buen ejemplo:

    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
    
    }

    Aquí está una pregunta sobre infinitos arroyos en Java: Es un infinito iterador mal diseño?

    Otro buen ejemplo son de primera clase de las funciones y cierres:

    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 no soporta la primera clase de funciones, y la imitación de los cierres anónimo de las clases internas no es muy elegante. Otra cosa este ejemplo muestra que en java no se puede hacer es ejecutar el código de un intérprete/REPL. Esto me parece inmensamente útil para probar rápidamente los fragmentos de código.

    • Por favor, tenga en cuenta que el tamiz es demasiado lento como para ser práctico.
    • Donde es el Java?
    • no hay ningún equivalente en java para estos ejemplos.
    • No es cierto. Usted puede fácilmente subclase de Java Iterable y Iterator para producir infinitos arroyos.
    • Acepto la corrección. La respuesta ha sido actualizado.
    • cosa que en este ejemplo se muestra que en java no se puede hacer es ejecutar el código de un intérprete/REPL. Esto me parece inmensamente útil para probar rápidamente los fragmentos de código.» Yo uso una página de álbum de recortes en Eclipse para probar fragmentos de código Java. Haciendo la mayoría, si no todos Java de trabajo en que los IDE, no necesito REPL. He utilizado notepad.exe y javac en mis primeros días, cuando yo no estaba seguro acerca de un idioma o de la operación de biblioteca y después de un corto período de tiempo que fue muy bien y rápido aunque un REPL es algo más fácil de usar y más rápido. Yo podría haber evitado el bloc de notas hack totalmente por la instalación de VisualAge que ya teníamos en

  18. 0

    Este Scala código…

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

    …sería completamente ilegible en Java, si es posible.

    • MI correcto OPINIO: gracias por la respuesta! pero podrías por favor explicar lo que sucede allí? No estoy familiarizado con la Scala de sintaxis, sin embargo, y (que es la posible razón de por qué), su apariencia es completamente ilegible hasta ahora para mí.
    • Es el particionamiento de una lista genérica de tipo T mediante una función de partición como un guardia en el patrón de coincidencia de las cláusulas de la declaración de caso.
    • Raro. Yo no soy ni remotamente Scala de expertos y puede darse cuenta de eso.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea