24、Spark核心编程之action操作开发实战

reduce

案例:有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
reduce操作的原理
首先将第一个和第二个元素,传入call()方法,进行计算,会获取一个结果,比如1 + 2 = 3
接着将该结果与下一个元素传入call()方法,进行计算,比如3 + 3 = 6
以此类推
所以reduce操作的本质,就是聚合,将多个元素聚合成一个元素
Java版本

public static void reduce() {
        // 创建SparkConf
        SparkConf sparkConf = new SparkConf().setAppName("reduceJava").setMaster("local");
        // 创建JavaSparkContext
        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);

        // 有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
        // 创建集合
        List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 并行化集合,创建初始化RDD
        // reduce操作的原理:
        // 首先将第一个和第二个元素,传入call()方法,进行计算,会获取一个结果,比如1 + 2 = 3
        // 接着将该结果与下一个元素传入call()方法,进行计算,比如3 + 3 = 6
        // 以此类推
        // 所以reduce操作的本质,就是聚合,将多个元素聚合成一个元素
        JavaRDD<Integer> numsRDD = javaSparkContext.parallelize(nums);

        Integer sum = numsRDD.reduce(new Function2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer integer, Integer integer2) throws Exception {
                return integer + integer2;
            }
        });

        System.out.println("sum = " + sum);

        // 关闭javaSparkContext
        javaSparkContext.close();
    }

scala版本

  def reduce(): Unit = {
    val conf = new SparkConf().setAppName("reduceScala").setMaster("local")
    val context = new SparkContext(conf)
    val numsRDD = context.parallelize(1 to 10)
    val sum = numsRDD.reduce(_ + _)
    println("sum = " + sum)
  }

collect

不用foreach action操作,在远程集群上遍历rdd中的元素,而使用collect操作,将分布在远程集群上的doubleNumbers RDD的数据拉取到本地
这种方式,一般不建议使用,因为如果rdd中的数据量比较大的话,比如超过1万条
那么性能会比较差,因为要从远程走大量的网络传输,将数据获取到本地
此外,除了性能差,还可能在rdd中数据量特别大的情况下,发生oom异常,内存溢出
因此,通常,还是推荐使用foreach action操作,来对最终的rdd元素进行处理
Java版本

    public static void collect() {
        // 创建SparkConf
        SparkConf sparkConf = new SparkConf().setAppName("collectJava").setMaster("local");
        // 创建JavaSparkContext
        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);

        // 创建集合
        List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 并行化集合,创建初始化RDD

        JavaRDD<Integer> numsRDD = javaSparkContext.parallelize(nums);

        JavaRDD<Integer> doubleNumsRDD = numsRDD.map(new Function<Integer, Integer>() {
            @Override
            public Integer call(Integer integer) throws Exception {
                return integer * 2;
            }
        });
        // 不用foreach action操作,在远程集群上遍历rdd中的元素,而使用collect操作,将分布在远程集群上的doubleNumbers RDD的数据拉取到本地
        // 这种方式,一般不建议使用,因为如果rdd中的数据量比较大的话,比如超过1万条
        // 那么性能会比较差,因为要从远程走大量的网络传输,将数据获取到本地
        // 此外,除了性能差,还可能在rdd中数据量特别大的情况下,发生oom异常,内存溢出
        // 因此,通常,还是推荐使用foreach action操作,来对最终的rdd元素进行处理
        List<Integer> doubleNums = doubleNumsRDD.collect();
        for(Integer integer : doubleNums) {
            System.out.println("integer = " + integer);
        }

        // 关闭javaSparkContext
        javaSparkContext.close();
    }

scala版本

  def collect(): Unit = {
    val conf = new SparkConf().setAppName("collectScala").setMaster("local")
    val context = new SparkContext(conf)
    val numsRDD = context.parallelize(1 to 10)
    val doubleNumsRDD = numsRDD.map(_ * 2)
    val doubleNums = doubleNumsRDD.collect()
    for(e <- doubleNums) println("e = " + e)
  }

count

count操作,统计它有多少个元素
Java版本

    public static void count() {
        // 创建SparkConf
        SparkConf sparkConf = new SparkConf().setAppName("countJava").setMaster("local");
        // 创建JavaSparkContext
        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);

        // 创建集合
        List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 并行化集合,创建初始化RDD

        JavaRDD<Integer> numsRDD = javaSparkContext.parallelize(nums);
        // 对rdd使用count操作,统计它有多少个元素
        long countNum = numsRDD.count();

        System.out.println("countNum = " + countNum);

        // 关闭javaSparkContext
        javaSparkContext.close();
    }

scala版本

  def count(): Unit = {
    val conf = new SparkConf().setAppName("countScala").setMaster("local")
    val context = new SparkContext(conf)
    val numsRDD = context.parallelize(1 to 10)
    val countNumber = numsRDD.count()
    println("countNumber = " + countNumber)
  }

take

take操作,与collect类似,也是从远程集群上,获取rdd的数据,但是collect是获取rdd的所有数据,take只是获取前n个数据
Java版本

    public static void take() {
        // 创建SparkConf
        SparkConf sparkConf = new SparkConf().setAppName("takeJava").setMaster("local");
        // 创建JavaSparkContext
        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);

        // 创建集合
        List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 并行化集合,创建初始化RDD

        JavaRDD<Integer> numsRDD = javaSparkContext.parallelize(nums);

        // take操作,与collect类似,也是从远程集群上,获取rdd的数据
        // 但是collect是获取rdd的所有数据,take只是获取前n个数据
        List<Integer> takeNumbers = numsRDD.take(5);
        for(Integer integer : takeNumbers) {
            System.out.println("integer = " + integer);
        }

        // 关闭javaSparkContext
        javaSparkContext.close();

    }

scala版本

  def take(): Unit = {
    val conf = new SparkConf().setAppName("takeScala").setMaster("local")
    val context = new SparkContext(conf)
    val numsRDD = context.parallelize(1 to 10)
    val takeNumbers = numsRDD.take(5)
    for(e <- takeNumbers) println("e = " + e)
  }

saveAsTextFile

直接将rdd中的数据,保存在HFDS文件中
但是要注意,我们这里只能指定文件夹,也就是目录
doubleNumbers.saveAsTextFile("hdfs://spark1:9000/double_number.txt");
那么实际上,会保存为目录中的/double_number.txt/part-00000文件
Java版本

    public static void saveAsTextFile() {
        // 创建SparkConf
        SparkConf sparkConf = new SparkConf().setAppName("saveAsTextFileJava");
        // 创建JavaSparkContext
        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);

        // 有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
        // 创建集合
        List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 并行化集合,创建初始化RDD

        JavaRDD<Integer> numsRDD = javaSparkContext.parallelize(nums);

        JavaRDD<Integer> doubleNumsRDD = numsRDD.map(new Function<Integer, Integer>() {
            @Override
            public Integer call(Integer integer) throws Exception {
                return integer * 2;
            }
        });

        doubleNumsRDD.saveAsTextFile("hdfs://hadoop-100:9000/doubleNumber.txt");

        // 关闭javaSparkContext
        javaSparkContext.close();

    }

scala版本

  def saveAsTextFile(): Unit = {
    val conf = new SparkConf().setAppName("saveAsTextFileScala").setMaster("local")
    val context = new SparkContext(conf)
    val numsRDD = context.parallelize(1 to 10)
    numsRDD.saveAsTextFile("hdfs://hadoop-100:9000/numsRDD")
  }

countByKey

这就是countByKey的作用,统计每个key对应的元素个数
countByKey返回的类型,直接就是Map<String, Object>
Java版本

public static void countByKey() {
        // 创建SparkConf
        SparkConf sparkConf = new SparkConf().setAppName("countByKeyJava").setMaster("local");
        // 创建JavaSparkContext
        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);

        // 创建集合
        List<Tuple2<String, Integer>> scoreList = Arrays.asList(
                new Tuple2<String, Integer>("class1", 80),
                new Tuple2<String, Integer>("class2", 80),
                new Tuple2<String, Integer>("class1", 95),
                new Tuple2<String, Integer>("class2", 85)
        );
        // 并行化集合,创建初始化RDD
        JavaPairRDD<String, Integer> scoreListRDD = javaSparkContext.parallelizePairs(scoreList);
        // 对rdd应用countByKey操作,统计每个班级的学生人数,也就是统计每个key对应的元素个数
        // 这就是countByKey的作用,统计每个key对应的元素个数
        // countByKey返回的类型,直接就是Map<String, Object>
        Map<String, Object> classNumber = scoreListRDD.countByKey();
        for (Map.Entry<String, Object> map : classNumber.entrySet()) {
            System.out.println(map.getKey() + "班级有" + map.getValue() + "人");
        }

        // 关闭javaSparkContext
        javaSparkContext.close();

    }

scala版本

  def countByKey(): Unit = {
    val conf = new SparkConf().setAppName("countByKeyScala").setMaster("local")
    val context = new SparkContext(conf)
    val scores = Array(("class1", 80), ("class2", 80), ("class1", 95), ("class2", 85))
    val scoreRDD = context.parallelize(scores)
    val classNumber = scoreRDD.countByKey()
    for(e <- classNumber) println(e._1 + "班级有" + e._2  + "人")
  }

foreach

foreach,遍历RDD的元素,在远程集群上执行
Java版本

    public static void foreach() {
        // 创建SparkConf
        SparkConf sparkConf = new SparkConf().setAppName("foreachJava").setMaster("local");
        // 创建JavaSparkContext
        JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);

        // 有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
        // 创建集合
        List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 并行化集合,创建初始化RDD

        JavaRDD<Integer> numsRDD = javaSparkContext.parallelize(nums);
        numsRDD.foreach(new VoidFunction<Integer>() {
            @Override
            public void call(Integer integer) throws Exception {
                System.out.println("integer = " + integer);
            }
        });

        // 关闭javaSparkContext
        javaSparkContext.close();

    }

scala版本

  def foreach(): Unit = {
    val conf = new SparkConf().setAppName("foreachScala").setMaster("local")
    val context = new SparkContext(conf)
    val numsRDD = context.parallelize(1 to 10)
    numsRDD.foreach(num => println("num = " + num))
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 内容概要 《计算机试卷1》是一份综合性的计算机基础和应用测试卷,涵盖了计算机硬件、软件、操作系统、网络、多媒体技术等多个领域的知识点。试卷包括单选题和操作应用两大类,单选题部分测试学生对计算机基础知识的掌握,操作应用部分则评估学生对计算机应用软件的实际操作能力。 ### 适用人群 本试卷适用于: - 计算机专业或信息技术相关专业的学生,用于课程学习或考试复习。 - 准备计算机等级考试或职业资格认证的人士,作为实战演练材料。 - 对计算操作有兴趣的自学者,用于提升个人计算机应用技能。 - 计算机基础教育工作者,作为教学资源或出题参考。 ### 使用场景及目标 1. **学习评估**:作为学校或教育机构对学生计算机基础知识和应用技能的评估工具。 2. **自学测试**:供个人自学者检验自己对计算机知识的掌握程度和操作熟练度。 3. **职业发展**:帮助职场人士通过实际操作练习,提升计算机应用能力,增强工作竞争力。 4. **教学资源**:教师可以用于课堂教学,作为教学内容的补充或学生的课后练习。 5. **竞赛准备**:适合准备计算机相关竞赛的学生,作为强化训练和技能检测的材料。 试卷的目标是通过系统性的题目设计,帮助学生全面复习和巩固计算机基础知识,同时通过实际操作题目,提高学生解决实际问题的能力。通过本试卷的学习与练习,学生将能够更加深入地理解计算机的工作原理,掌握常用软件的使用方法,为未来的学术或职业生涯打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值