zoukankan      html  css  js  c++  java
  • 【原创】大叔经验分享(17)编程实践对比Java vs Scala

    scala

    官方地址 https://www.scala-lang.org/

    本文尽可能包含了一些主要的java和scala在编程实践时的显著差异,展现scala的代码的简洁优雅;scala通吃<面向对象编程Object Oriented Programming>和<函数式编程Functional Programming>,有很多开源组件都用scala开发(比如spark、kafka等),虽然java从8开始支持lambda表达式,有些方面已经接近scala,但是...

    直接看代码对比:

    一 Loop循环

    1 for

    取出0-10之间的偶数

    scala

        for (i <- 0 to 10 if i % 2 == 0) println(i)
        //or
        for (i <- 0 to 5) println(i * 2)
        //or
        for (i <- 0 until 6) println(i * 2)
    //or
    Array.range(0, 10, 2).foreach(println)

     java

            for (int i = 0; i <= 10; i++) {
                if (i % 2 == 0) {
                    System.out.println(i);
                }
            }
            //or
            for (int i = 0; i <= 10; i += 2) {
                System.out.println(i);
            }
            //or
            for (int i = 0; i <= 5; i++) {
                System.out.println(i * 2);
            }

    输出
    0
    2
    4
    6
    8
    10

    2 foreach

    迭代输出

    scala

    val list = List(2, 4, 1, 3, 5)
    list.foreach(println)

    java

            List<Integer> list = Arrays.asList(new Integer[]{2, 4, 1, 3, 5});
            for (Integer item : list) {
                System.out.println(item);
            }
            //or
            list.forEach((item) -> System.out.println(item));

    输出
    2
    4
    1
    3
    5

    二 Functional函数式

    函数式即将函数作为变量的一种,来看常见的包装应用

    scala

        def wrapper(str : String, f : ((String) => String)): Unit = {
          println("wrapper start")
          println(f(str))
          println("wrapper end")
        }
        def say(str : String) : String = "hello " + str
        wrapper("test", say)
        //or
        wrapper("test", (str => "hello " + str))

    java

        interface SayInterface {
            public String say(String str);
        }
        public void wrapper1(String str, SayInterface si) {
            System.out.println("wrapper start");
            System.out.println(si.say(str));
            System.out.println("wrapper end");
        }
        //or
        public void wrapper2(String str, Function<String, String> f) {
            System.out.println("wrapper start");
            System.out.println(f.apply(str));
            System.out.println("wrapper end");
        }
    
            this.wrapper1("test", new SayInterface() {
                @Override
                public String say(String str) {
                    return "hello " + str;
                }
            });
            //or
            this.wrapper1("test", ((item) -> "hello " + item));
            //or
            this.wrapper2("test", ((item) -> "hello " + item));

    在早期的Java中函数式等价于命令模式,需要定义一个命令接口,然后可以传入不同的接口实现,这样又形成策略模式,比如jdk的排序接口;

    输出
    wrapper start
    hello test
    wrapper end

    三 Array Collection

    1 数组相加

    scala

        val arr1 = Array(1, 2)
        val arr2 = ArrayBuffer(1, 3)
        arr2 += (4)
        val arr3 = arr1 ++ arr2
        println(arr3.mkString(","))

    java

            Integer[] arr1 = new Integer[]{1, 2};
            Integer[] arr2 = new Integer[]{1, 3};
            Integer[] arr3 = new Integer[arr1.length + arr2.length];
            for (int i = 0; i < arr1.length; i++) {
                arr3[i] = arr1[i];
            }
            for (int i = 0; i < arr2.length; i++) {
                arr3[arr1.length + i] = arr2[i];
            }
            for (Integer item : arr3) {
                System.out.println(item);
            }
            //or
            List<Integer> list = new ArrayList<>();
            list.addAll(Arrays.asList(arr2));
            list.addAll(Arrays.asList(arr3));
            list.add(4);
            list.forEach((item) -> System.out.println(item));

    输出
    1,2,1,3

    2 创建Map及添加entry

    scala

    //    val map1 = Map("a" -> 1, "b" -> 2, "c" -> 3)
        var map1 = Map("a" -> 1, "b" -> 2)
        map1 += ("c" -> 3)
        map1.foreach(println)

    java

            Map<String, Integer> map1 = new HashMap<>();
            map1.put("a", 1);
            map1.put("b", 2);
            map1.put("c", 3);
            map1.forEach((key, value) -> System.out.println(key + ", " + value));

    输出
    (a,1)
    (b,2)
    (c,3)

    3 合并两个Map

    两个Map中key相同时将value相加

    scala

        val map1 = Map("a" -> 1, "b" -> 2)
        val map2 = Map("a" -> 1, "c" -> 3)
        Array.concat(map1.toArray, map2.toArray).groupBy(_._1).map(item => (item._1, item._2.map(_._2).reduce(_ + _))).foreach(println)

    java

            Map<String, Integer> map1 = new HashMap<>();
            map1.put("a", 1);
            map1.put("b", 2);
            Map<String, Integer> map2 = new HashMap<>();
            map2.put("a", 1);
            map2.put("c", 3);
            //merge map1 and map2 to mapMerge
            Map<String, Integer> mapMerge = new HashMap<>();
            mapMerge.putAll(map1);
            for (String key : map2.keySet()) {
                if (mapMerge.containsKey(key)) {
                    mapMerge.put(key, mapMerge.get(key) + map2.get(key));
                } else {
                    mapMerge.put(key, map2.get(key));
                }
            }
            mapMerge.forEach((key, value) -> System.out.println(key + ", " + value));

    输出
    (b,2)
    (a,2)
    (c,3)

    4 mkString

    将集合元素逗号分隔输出

    scala

        val arr = Array(2, 4, 1, 3, 5)
        println(arr.mkString(","))

    java

        public String mkStringInJava(Object[] arr, String seperator) {
            StringBuffer buf = new StringBuffer();
            for (Object item : arr) {
                buf.append(seperator).append(item);
            }
            return buf.toString().substring(seperator.length());
        }
    
            Integer[] arr = new Integer[]{2, 4, 1, 3, 5};
            System.out.println(this.mkStringInJava(arr, ","));

    输出
    2,4,1,3,5

    5 统计最小、最大、平均值

    scala

        val arr = Array(2, 4, 1, 3, 5)
        println(arr.min + ", " + arr.max + ", " + arr.sum.toDouble / arr.length)

    java

            Integer[] arr = new Integer[]{2, 4, 1, 3, 5};
            Integer min = null;
            Integer max = null;
            Integer sum = 0;
            for (Integer item : arr) {
                sum += item;
                if (min == null || min > item) {
                    min = item;
                }
                if (max == null || max < item) {
                    max = item;
                }
            }
            System.out.println(min + ", " + max + ", " + ((double)sum / arr.length));

    输出
    1, 5, 3.0

    6 简单排序

    正序、倒叙

    scala

        val arr = Array(2, 4, 1, 3, 5)
        //1
        println(arr.sorted.mkString(","))
        //2
        println(arr.sorted.reverse.mkString(","))
        //3
        println(arr.sortWith((v1 : Int, v2 : Int) => v2 < v1).mkString(","))

    java

            Integer[] arr = new Integer[]{2, 4, 1, 3, 5};
            //1
            Arrays.sort(arr);
            for (Integer item : arr) {
                System.out.println(item);
            }
            //or
            Arrays.asList(arr).forEach((v) -> System.out.println(v));
            //2
            for (int i = arr.length - 1; i >= 0; i--) {
                System.out.println(arr[i]);
            }
            //3
            Arrays.sort(arr, new Comparator<Integer>(){
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o2 - o1;
                }
            });
            //or
            Arrays.sort(arr, ((Integer v1, Integer v2) -> v2 - v1));
            for (Integer item : arr) {
                System.out.println(item);
            }

    输出
    1,2,3,4,5
    5,4,3,2,1
    5,4,3,2,1

    7 flatMap distinct

    将数组中每个元素拆成多个元素并去重

    scala

        val arr = Array("1,2,3", "1,4,5")
        arr.flatMap(_.split(",")).distinct.foreach(println)

    java

            String[] arr = new String[]{"1,2,3", "1,4,5"};
            Set<String> set = new HashSet<>();
            for (String item : arr) {
                set.addAll(Arrays.asList(item.split(",")));
            }
            set.forEach((item) -> System.out.println(item));

    输出
    1
    2
    3
    4
    5

    8 foldLeft

    将数组中值为奇数的元素求和

    scala

        val arr = Array(2, 4, 1, 3, 5)
        println(arr.foldLeft(0)((result, item) => result + (if (item % 2 != 0) item else 0)))

    java

            Integer[] arr = new Integer[]{2, 4, 1, 3, 5};
            Integer sumOdd = 0;
            for (Integer item : arr) {
                if (item % 2 == 1) {
                    sumOdd += item;
                }
            }
            System.out.println(sumOdd);

    输出
    9

    9 filter map collect

    将数组中小于3的元素提取一个新的集合,同时将新集合中的每个元素*3

    scala

        val arr = Array(2, 4, 1, 3, 5)
        arr.filter(_ < 3).map(_ * 3).foreach(println)
        //or
        arr.collect({case item : Int if item < 3 => item * 3}).foreach(println)

    java

            Integer[] arr = new Integer[]{2, 4, 1, 3, 5};
            List<Integer> result = new ArrayList<>();
            for (Integer item : arr) {
                if (item < 3) {
                    result.add(item * 3);
                }
            }
            result.forEach((item) -> System.out.println(item));

    输出
    6
    3

    三 Tuple及Bean

    1 定义bean class

    scala

        class Dummy(val name : String, val age : Int){
          override def toString = name + "," + age
        }

    java

            class Dummy {
                public Dummy(String name, Integer age) {
                    this.name = name;
                    this.age = age;
                }
                @Override
                public String toString() {
                    return this.name + "," + this.age;
                }
                private String name = null;
                private Integer age = null;
                public String getName() {
                    return name;
                }
                public void setName(String name) {
                    this.name = name;
                }
                public Integer getAge() {
                    return age;
                }
                public void setAge(Integer age) {
                    this.age = age;
                }
            }

    熟悉的java bean class定义,field、getter、setter、constructor、toString等;

    2 Bean复杂排序

    scala

        val arr1 = Array(new Dummy("a", 1), new Dummy("b", 3), new Dummy("a", 2), new Dummy("b", 1))
        //1
        println(arr1.sortBy(_.name).mkString("-"))
        //2
        println(arr1.sortBy(_.age).mkString("-"))
        //3
        println(arr1.sortWith((item1, item2) => if (item1.name.equals(item2.name)) item1.age < item2.age else item1.name.compareTo(item2.name) < 0).mkString("-"))

    java

            Dummy[] arr = new Dummy[]{new Dummy("a", 1), new Dummy("b", 3), new Dummy("a", 2), new Dummy("b", 1)};
            //1
            Arrays.sort(arr, new Comparator<Dummy>(){
                @Override
                public int compare(Dummy d1, Dummy d2) {
                    return d1.getName().compareTo(d2.getName());
                }
            });
            //or
            Arrays.sort(arr, ((Dummy d1, Dummy d2) -> d1.getName().compareTo(d2.getName())));
            //or
            Arrays.sort(arr, Comparator.comparing(Dummy::getName));
            System.out.println(this.mkStringInJava(arr, "-"));
            //2
            Arrays.sort(arr, Comparator.comparing(Dummy::getAge));
            System.out.println(this.mkStringInJava(arr, "-"));
            //3
            Arrays.sort(arr, ((Dummy d1, Dummy d2) -> {
                Integer result = d1.getName().compareTo(d2.getName());
                return result != 0 ? result : d1.getAge() - d2.getAge();
            }));
            System.out.println(this.mkStringInJava(arr, "-"));

    输出
    a,1-a,2-b,3-b,1
    a,1-b,1-a,2-b,3
    a,1-a,2-b,1-b,3

    3 Tuple

    scala

        def statistics(arr : Array[Int]) : (Int, Int, Double) = (arr.min, arr.max, arr.sum.toDouble / arr.length)
        val arr = Array(2, 4, 1, 3, 5)
        val s = statistics(arr)
        println(s._1 + ", " + s._2 + ", " + s._3)

    java

        class Statistics {
            private Integer min = null;
            private Integer max = null;
            private Double avg = null;
            public Integer getMin() {
                return min;
            }
            public void setMin(Integer min) {
                this.min = min;
            }
            public Integer getMax() {
                return max;
            }
            public void setMax(Integer max) {
                this.max = max;
            }
            public Double getAvg() {
                return avg;
            }
            public void setAvg(Double avg) {
                this.avg = avg;
            }
        }
        public Statistics statistics(Integer[] arr) {
            Statistics result = new Statistics();
            Integer min = null;
            Integer max = null;
            Integer sum = 0;
            for (Integer item : arr) {
                sum += item;
                if (min == null || min > item) {
                    min = item;
                }
                if (max == null || max < item) {
                    max = item;
                }
            }
            result.setMin(min);
            result.setMax(max);
            result.setAvg((double)sum / arr.length);
            return result;
        }
    
            Integer[] arr = new Integer[]{2, 4, 1, 3, 5};
            Statistics s = statistics(arr);
            System.out.println(s.getMin() + ", " + s.getMax() + ", " + s.getAvg());

    java中方法返回多个值时通常需要借助class来实现(将多个值作为class的属性);

    输出
    1, 5, 3.0

    4 Tuple排序

    scala

        val arr = Array(("a", 1), ("b", 3), ("a", 2), ("b", 1))
        println(arr.sortBy(_._1).mkString("-"))
        println(arr.sortBy(_._2).mkString("-"))
        println(arr.sortWith((item1, item2) => if (item1._1.equals(item2._1)) item1._2 < item2._2 else item1._1.compareTo(item2._1) < 0).mkString("-"))

    java中需要借助第三方库才能支持数量有限的Tuple,这里不演示了;

    输出
    (a,1)-(a,2)-(b,3)-(b,1)
    (a,1)-(b,1)-(a,2)-(b,3)
    (a,1)-(a,2)-(b,1)-(b,3)

    四 IO

    1 read读文件

    scala

        Source.fromFile("test.log").getLines().foreach(println)

    java

            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new FileReader(new File("test.log")));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

    2 write写文件

    scala

        var writer : PrintWriter = null
        try {
          writer = new PrintWriter("test.log")
          writer.write("test")
          writer.flush()
        } catch {case e : Exception => e.printStackTrace}
        finally {try {if (writer != null) writer.close()} catch {case e : Exception => e.printStackTrace}}

    java

            BufferedWriter writer = null;
            try {
                writer = new BufferedWriter(new FileWriter(new File("test.log")));
                writer.write("test");
                writer.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (writer != null) {
                    try {
                        writer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

    五 Actor 定时

    akka.actor

    1 Actor

    scala

    import akka.actor.{Actor, ActorSystem, Props}
    import akka.util.Timeout
        class TestActor extends Actor {
          def receive = {
            case arg => {
              val result = "hello : " + arg
              println(result)
              Thread.sleep(3000)
              result
            }
          }
        }
        val system = ActorSystem("ActorSystem")
        val actor = system.actorOf(Props(new TestActor), "TestActor")
        actor ! "world async"
        implicit val timeout = Timeout(5, TimeUnit.SECONDS)
        import akka.pattern._
        val feature = actor ? "world async with feature"
        feature.foreach(result => println(result))

    java

    java.util.concurrent.LinkedBlockingQueue
    java.util.concurrent.ThreadPoolExecutor
    java.util.concurrent.Callable
    java.util.concurrent.Future
    实现效果:异步非阻塞,object接收消息放到queue中,同时内置ThreadPool不断处理消息;

    2 定时

    scala

        val system = ActorSystem("ActorSystem")
        import system.dispatcher
        system.scheduler.schedule(Duration.create(1000, TimeUnit. MILLISECONDS), Duration.create(1000, TimeUnit. MILLISECONDS))(
          println("hello")
        )

    java

    java.util.Timer
    java.util.TimerTask
    实现效果:定时执行task;

    六 continue/break

    scala

    import scala.util.control.Breaks._
    
    breakable {
      ...
      break
      ...
    }

    java 原生支持

  • 相关阅读:
    TableEx 控件 v1.0 [原创][免费][开源]
    js刷新页面
    SimpleAjax 开发包 v3.1 (简单的Ajax)
    oracle中的''空字符串和null居然是等价的
    HTTP 错误大全
    Ext2.0 form使用实例
    isqlweb (Web版 SQL Server 管理器)
    关于软件版本
    我的第一个C++程序——方块游戏 v1.0
    轻松实现UltraWebGrid中的分页控制
  • 原文地址:https://www.cnblogs.com/barneywill/p/10159625.html
Copyright © 2011-2022 走看看