精华内容
下载资源
问答
  • Java8 对数组求和

    2021-06-11 15:17:37
    Java8 对数组求和 1.对BigDecimal数据求和 (1)简单数据求和 String[] a = {"1", "2", "3"}; BigDecimal sum = Arrays.asList(a).stream().map(x -> new BigDecimal(x)). reduce(BigDecimal.ZERO, BigDecimal::...

    Java8 对数组求和

    1.对BigDecimal数据求和
    (1)简单数据求和

    String[] a = {"1", "2", "3"};
     BigDecimal sum = Arrays.asList(a).stream().map(x -> new BigDecimal(x)). reduce(BigDecimal.ZERO, BigDecimal::add);
    

    (2)集合数据求和

     List<Map<String,Object>> list = new ArrayList<>();
     Map<String,Object> stu1 = new HashMap<String, Object>();
     stu1.put("name", "卫庄");
     stu1.put("score", new BigDecimal(80));
     list.add(stu1);
     Map<String,Object> stu2 = new HashMap<String, Object>();
     stu2.put("name", "盖聂");
     stu2.put("score", new BigDecimal(90));
     list.add(stu2);
     Map<String,Object> stu3 = new HashMap<String, Object>();
     stu3.put("name", "天明");
     stu3.put("score", new BigDecimal(60));
     list.add(stu3);
     BigDecimal sum = list.stream().map(x -> new BigDecimal(x.get("score").toString())).reduce(BigDecimal.ZERO,BigDecimal::add);
     System.out.println("三人总分:"+sum);
    

    2、对double类型数据求和
    (1)简单数据求和

    String[] a = {"1", "2", "3"};
    double sumA = Arrays.asList(a).stream().collect(Collectors.summingDouble(x -> Double.valueOf(x)));
    

    (2)集合数据求和

    List<Map<String,Object>> list = new ArrayList<>();
      Map<String,Object> stu1 = new HashMap<String, Object>();
      stu1.put("name", "卫庄");
      stu1.put("score", 80.0);
      list.add(stu1);
      Map<String,Object> stu2 = new HashMap<String, Object>();
      stu2.put("name", "盖聂");
      stu2.put("score", 90.0);
      list.add(stu2);
      Map<String,Object> stu3 = new HashMap<String, Object>();
      stu3.put("name", "天明");
      stu3.put("score", 60.0);
      list.add(stu3);
      double sum = list.stream().collect(Collectors.summingDouble(x -> ((Double) x.get("score"))));
      System.out.println("三人总分:"+sum);
    

    适应Java8的新特性,利用map做映射,将数据映射为我们需要的数据类型

    展开全文
  • 1.C++数组求和 vector<int> nums{1,2,3,4,5}; int sum = accumulate(nums.begin(),nums.end(),0); accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。 accumulate函数将它...

    1.C++数组求和

    vector<int> nums{1,2,3,4,5};
    int sum = accumulate(nums.begin(),nums.end(),0);
    

    accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。
    accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值。accumulate算法返回累加的结果,其返回类型就是其第三个实参的类型。
    如上述代码返回结果为0+1+2+3+4+5的值

    vector<string> v{"c","t","t"};
    cout<<accumulate(v.begin(),v.end(),string(" "))<<endl;
    

    如上述代码做字符串拼接

    2.java使用stream流
    Arrays.stream(nums).sum();

    展开全文
  • 数组求和???遍历一遍累加起来不就可以了吗??? 是的,你说的都对,都听你的,但是我说的就是数组求和,并且我也确实是刚刚学会。╮(╯▽╰)╭ 继续看下去吧,或许你的疑问会解开↓ 注:记录于学习完《Java 8 ...

    前言

    看到题目是不是有点疑问:你确定你没搞错?!数组求和???遍历一遍累加起来不就可以了吗???

    是的,你说的都对,都听你的,但是我说的就是数组求和,并且我也确实是刚刚学会。╮(╯▽╰)╭

    继续看下去吧,或许你的疑问会解开↓

    注:记录于学习完《Java 8 实战》数据并行处理与性能,如果有错误,欢迎大佬指正

    传统方式

    求和方法

    我相信你和我一样,提到数组求和,肯定最想想到的就是将数组迭代一遍,累加迭代元素。这是最简单的一种方式,代码实现如下:

    public static long traditionSum(long[] arr){
            //和
            long sum = 0;
            //遍历数组中的每个元素
            for (long l : arr) {
                //累加
                sum += l;
            }
            return sum;
        }
    

    性能测试方法

    为了便于我们测试性能,我们写一个比较通用的测试函数,用来记录对每种方式的运行时间,直接看代码吧!

    public static long test(Function<long[], Long> function, long[] arr){
            //记录最快的时间
            long fasttime = Long.MAX_VALUE;
            //对函数调用10次
            for (int i = 0; i < 10; i++) {
                //记录开始的系统时间
                long start = System.nanoTime();
                //执行函数
                long result = function.apply(arr);
                //获取运行时间转换为ms
                long time = (System.nanoTime() - start) / 1_000_000;
                //打印本次的就和结果
                System.out.println("结果为:" + result);
                //更新最快的时间
                if (time < fasttime) {
                    fasttime = time;
                }
            }
            return fasttime;
    
        }
    

    性能测试代码解释

    • 传入参数Function<long[], Long> function: 我们需要测试的函数,稍后我们会把每种求和方式都传入到这个参数里面。如果你对java 8的新特性(Lambda表达式、行为参数化、方法引用等)不熟悉,那么你可以理解为Function是一个匿名类,我们传入的求和方法会放到function.apply()的方法中,我们调用apply()方法,实际上就是调用我们传入的求和方法。
    • Function<long[], Long>的泛型: 第一个为我们求和方法需要传入的参数的类型(传入一个long类型的数组作为待求和数组),第二个为我们的求和方法返回值的类型(返回数组的和为long)
    • long[] arr:待求和数组
    • 关于为什么会调用10次:任何的Java代码都需要多执行几次才会被JIT编译器优化,多执行几次是为了保证我们测量性能的准确性。

    数据准备

    方法有了,我们当然要准备好我们的测试数据了,为了简便起见,我们直接顺序生成1到100,000,000(1亿)来最为待求和的数组:

    long[] longs = LongStream.rangeClosed(1, 100_000_000).toArray();
    

    测试性能

    数据有了,我们可以测试一下传统方式的性能了(所在类TestArraysSum)

    public static void main(String[] args) {
            long[] longs = LongStream.rangeClosed(1, 100_000_000).toArray();
            
            //执行测试函数
            long time = test(TestArraysSum::traditionSum, longs);
    
            System.out.println("时间为: " + time + "ms");
    
        }
    

    结果:

    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    时间为: 62ms
    

    继续看其他方式

    Stream流的顺序执行方式

    求和方法

    java 8的流可谓是非常的强大,配合lambda表达式和方法引用,极大的简化了对数据处理方面,下面是使用流对数组进行顺序求和

    public static long sequentialSum(long[] arr){
            return Arrays.stream(arr)
                    .reduce(0L, Long::sum);
        }
    

    代码解释

    • Arrays.stream(arr)将我们传入的数组变为一个流(此处没有Java包装类与原始类型的装箱和拆箱,装箱和拆箱会极大影响性能,应该尽量避免)
    • .reduce(0L, Long::sum):0L是初始值,Long::sum通过方法引用的方式使用Long提供的求和函数,对数组的每一个元素都进行求和

    性能测试

    Java 8让我们的代码极大的简化了,那么性能如何呢?
    我们将main方法内执行求和方法部分换为调用这个方法看看

    long time = test(TestArraysSum::sequentialSum, longs);
    
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    时间为: 62ms
    

    emmmm 好像差不多,Ծ‸Ծ,先不急,Java 8的流给我们带来的另一大好处还没用上呢,下面我们就来看看吧

    Stream流的并行执行

    求和方法

    Java 8 的Stream流可以让我们非常简单的去使用多线程解决问题,而我们的求和需求好像完美适合多线程问题去解决

    public static long parallelSum(long[] arr){
            return Arrays.stream(arr)
                    .parallel()
                    .reduce(0L, Long::sum);
        }
    

    代码解释

    • .parallel():与顺序流实现相比,仅仅是多调用了一个parallel()方法,他的作用就是将顺序流转化为并行流(其实就是改变了一下boolean标志),如何并行执行呢,不用我们实现,无脑调用就好了

    性能测试

    long time = test(TestArraysSum::parallelSum, longs);
    

    结果

    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    时间为: 52ms
    

    哦吼~这就很舒服了,是不是瞬间就快了

    注:并行流内部默认使用ForkJoinPool的线程池,线程数量默认为计算机处理器的数量,使用Runtime.getRuntime().availableProcessors()可以获取处理器核心数
    (我的测试环境是8个),可是设置这个值,但是只能全局设置,所以最好还是不要更改

    是不是疑问我们除了调用parallel()方法以外什么都没干,究竟是怎么实现多线程的呢,其实并行流底层使用的是Java 7的分支/合并框架,下面我们就看一下使用分支/合并框架实现多线程求和吧!

    分支合并框架的实现方式

    分支合并框架的目的是以递归的方式将可以并行的任务拆分成更小的子任务,然后将每个子任务的结果进行合并生成整体结果。

    求和方法

    我们可以继承RecursiveTask实现其compute()方法
    分支合并实现的类ForkJoinSumCalculator

    package java_8.sum;
    
    import java.util.concurrent.RecursiveTask;
    
    public class ForkJoinSumCalculator extends RecursiveTask<Long> {
    
        //任务处理的数组
        private final long[] arr;
        //当前任务处理的开始和结束索引
        private final int start;
        private final int end;
    
        //划分到处理数组的长度10_000_000变不来划分,进而合并
        public static final long THRESHOLD = 10_000_000;
    
        //公共的构造函数,用来创建主任务
        public ForkJoinSumCalculator(long[] arr){
            this(arr,0,arr.length);
        }
    
        //私有的构造函数,用来创建子任务
        private ForkJoinSumCalculator(long[] arr, int start, int end){
            this.arr = arr;
            this.start = start;
            this.end = end;
        }
    
        //实现的方法
        @Override
        protected Long compute() {
            //当时子任务处理长度
            int length = end - start;
            //当数组处理长度足够小时
            if (length <= THRESHOLD){
                //进行合并
                return computeSequentially();
            }
    
            //创建第1个子任务对前面一半数组进行求和
            ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(arr, start, start + length / 2);
            //使用线程池中的另一个线程求和前一半
            leftTask.fork();
            //创建第2个子任务对后一半数组进行求和
            ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(arr, start + length / 2, end);
            //直接使用当前线程进行求和 获取求和结果
            Long rightResult = rightTask.compute();
            //获取前一半的求和结果
            Long leftTesult = leftTask.join();
            //合并
            return leftTesult + rightResult;
    
        }
    
        //合并是的调用方法 迭代求和
        private long computeSequentially(){
            long sum = 0;
            for (int i = start; i < end; i++) {
                sum += arr[i];
            }
            return sum;
        }
    }
    
    

    public static final long THRESHOLD = 10_000_000;
    划分的界线使我随便设定的当前值的情况下会划分为10个线程

    然后我们就可以编写我们的求和方法了

        public static long forkJoinSum(long[] arr){
            ForkJoinSumCalculator calculator = new ForkJoinSumCalculator(arr);
            return new ForkJoinPool().invoke(calculator);
        }
    

    性能测试

    long time = test(TestArraysSum::forkJoinSum, longs);
    

    结果:

    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    结果为:5000000050000000
    时间为: 53ms
    

    还不错,跟并行流的性能差不多

    由于分支合并时的递归调用也消耗性能,因此我们更改public static final long THRESHOLD = 10_000_000;的大小时,运行时间会差距很大。
    具体更改多少效率最高,这个真的不好说

    总结

    • 使用了4种方式完成数组求和
    • 使用传统方式(遍历)效率其实也不低,因为实现方式比较接近底层
    • 使用流极大简化了数组处理
    • 并行流在适合的场景下可以大展身手
    • 并行流使用分支合并框架实现

    个人公众号

    我的个人公众号已经开通了,正在按计划建设中,以后的文章会第一时间发布在公众号中,同时也给大家准备了亿点学习资料,关注公众号后台发送:学习资料

    展开全文
  • } } 运行结果 三、数组求和 代码实现 public class _03数组求和 { public static void main(String[] args) { int res = f(new int[] {1,2,3,4,5},0); System.out.println(res); } static int f(int []...

    一、求阶乘

    分析

    在这里插入图片描述

    代码实现

    public class _02求阶乘 {
    	public static void main(String[] args) {
    		int res = f(5);
    		System.out.println(res);
    	}
    
    	//f(n)求n的阶乘,f(n-1)求n-1的阶乘
    	static int f(int n) {
    		if(n == 1) return 1;
    		return n * f(n-1);
    	}
    }
    
    

    运行结果

    在这里插入图片描述


    二、打印 i 到 j

    代码实现

    public class _03打印i到j {
    	public static void main(String[] args) {
    		f(10,15);
    	}
    
    	static void f(int i,int j) {
    		if(i>j) return;
    		System.out.println(i);
    		f(i+1, j);
    	}
    }
    
    

    运行结果

    在这里插入图片描述

    三、数组求和

    代码实现

    public class _03数组求和 {
    	public static void main(String[] args) {
    		
    		int res = f(new int[] {1,2,3,4,5},0);
    		System.out.println(res);
    	}
    
    	static int f(int []arr,int begin) {
    		
    		if(begin == arr.length-1) return arr[begin];
    		return arr[begin]+f(arr, begin+1);
    	}
    }
    
    

    运行结果

    在这里插入图片描述

    四、翻转字符串

    代码实现

    public class _03翻转字符串 {
    	public static void main(String[] args) {
    		
    		System.out.println(reverse("abcd", 3));
    	}
    
    	static String reverse(String src,int end) {
    		
    		if(end == 0) 
    			return ""+src.charAt(0);
    		
    		return src.charAt(end)+reverse(src, end-1);
    	}
    }
    
    

    运行结果

    在这里插入图片描述

    展开全文
  • 趣味编程:不使用循环对数组求和

    千次阅读 2011-10-21 09:12:48
    sum函数使用普通的for each循环对数组求和。 sum([1, 2, 3, 4]) = 0 + 1 + 2 + 3 + 4 sum2函数不使用循环而是用递归(左折叠)方式对数组求和。 sum2([1, 2, 3, 4]) = (((0 + 1) + 2) + 3) + 4 sum3函数不使用...
  • JS中对数组进行求和

    千次阅读 2019-03-14 08:43:35
    如果在一个数组想对数组中的所有项进行求和(当然每项都得是Number对象)该怎么做呢? 可以使用Array对象的reduce或reduceRight方法。这两个方法会遍历数组中的每个对象,并最终返回一个值。 这两个方法都接受两个...
  • 多线程对数组进行求和

    千次阅读 2011-10-02 20:22:30
     2:每个线程对数组的部分元素进行求和。 3:等待所有线程执行完毕,返回结果。 说明: 在论坛中看到有一个帖子是使用concurrent包实现的,我这个例子没有使用concurrent包。发现也挺简单。 代码如下所示:  ...
  • <p>I got the following array from my code.... <pre><code>foreach($JobworkMaterialJson as $key => $value) { $decode = json_decode($value->jobcard_jobwork_json);...<p>by the print_r($decode), I ...
  • 测试结果:
  • 使用java8的stream对数组进行求和

    千次阅读 2019-09-21 14:21:52
    1.对BigDecimal类型的值求和 List<Map<String,Object>> list = new ArrayList<>();Map<String,Object> stu1 = new HashMap<String, Object>();stu1.put("name", "卫庄");stu1.pu...
  • 两个对数组元素求和,求积的算法题求数组的子数组元素和的最大值。 思路: 遍历数组一遍,如果遇到负数则对累加结果清零。同时记录累加值所达到的最大值。代码块int maxsum(int *num, int n) //求数组子数组和的...
  • <p>I am new developer. I have a problem. I want all rating value sum then divided with 5. foreach show 325. I want result 3+2+5=10 then 10/5=...<pre><code> foreach ($ratings as $ratingss) { ... </div>
  • 对数组中所有的值求和 在写购物车是用到了数组中多个值的求和 本来是用循环去写的但是发现太麻烦了 后来发现了数组中的reduce方法 下面展示一些 内联代码片。 // An highlighted block var numbers = [3, 5, 7, 66, ...
  • 编写函数对数组中的元素求和

    千次阅读 2018-04-03 11:39:56
    编写函数 add_array 对数组中的元素求和,函数原型为: void add_array(int a, int *sum); 该函数可以重复调用多次,每次只使用参数a传入数组中的一个元素,函数内部可以累计历次传入的值进行求和,每次执行后均把...
  • C++ 编写函数对数组中的元素求和

    千次阅读 2018-04-07 17:57:02
    题目内容:编写函数 add_array 对数组中的元素求和,函数原型为:void add_array(int a, int *sum);该函数可以重复调用多次,每次只使用参数a传入数组中的一个元素,函数内部可以累计历次传入的值进行求和,每次执行...
  • <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Array.prototype.reduce()</title> </head> <body> <...
  • C++实验——对数组进行遍历求和

    千次阅读 2019-03-07 17:22:07
    #include&lt;iostream.h&gt; #include&lt;math.h&gt; int main() { int i,sum=0; int a[10]; cout&lt;&lt;"请输入10个数:"; for(i=0;i&lt;10;i++) ......
  • ... Previously, I had a <code>while</code> loop to select all records between two dates which then carried out another query on the payments table within the loop. This was painfully slow so i have ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 402
精华内容 160
关键字:

对数组求和