流API--分组和分片

分组和分片
对具有相同特性的值进行分组时一个很常见的任务,我们可以直接使用groupingBy来进行分组。
当分类函数是一个predicate函数时,流会被分成2组列表,一组返回true,一组返回false。

public class Test
{


	public static void main(String[] args)
	{
		Stream<Person> stream = Stream.of(new Person("1", "林肯"), new Person("2", "冰儿"));
		Map<String, List<Person>> collect = stream.collect(Collectors.groupingBy(Person::getId));
		for (String string : collect.keySet())
		{
			System.out.println(string + "-->" + collect.get(string));
		}


		System.out.println("=====华丽丽的分割线==========");
		Stream<Person> stream1 = Stream.of(new Person("1", "林肯"), new Person("2", "冰儿"), new Person("3", "忽忽"));
		Map<Boolean, List<Person>> collect2 = stream1.collect(Collectors.partitioningBy(Person::isMyLove));
		for (boolean string : collect2.keySet())
		{
			System.out.println(string + "-->" + collect2.get(string));
		}


	}


}


class Person
{
	private String id;
	private String name;


	public Person(String id, String name)
	{
		this.id = id;
		this.name = name;
	}


	public boolean isMyLove()
	{
		if ("冰儿".equals(name))
		{
			return true;
		}
		return false;
	}


	public String getId()
	{
		return id;
	}


	public void setId(String id)
	{
		this.id = id;
	}


	public String getName()
	{
		return name;
	}


	public void setName(String name)
	{
		this.name = name;
	}


	@Override
	public String toString()
	{
		return "Person [id=" + id + ", name=" + name + "]";
	}


}


java8还提供了一些其他的收集器,用来对分组后的元素进行downstream处理,这几个收集器都是Collectors的静态方法,具体介绍如下:
1,counting方法会返回收集元素的总个数。代码如下:
Map<Boolean, Long> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.counting()));
2,summing(Int|long|Double)方法接受一个函数作为参数,它会将该函数应用到downstream元素中,并生成他们的求和。代码如下:
Map<Boolean, Integer> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.summingInt(a -> new Integer(((Person) a).getId()))));
3,maxBy方法和minBy方法会接受一个比较器,并生成downstream元素的最大值和最小值。代码如下:
Map<Boolean, Optional<Person>> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.maxBy(Comparator.comparing(Person::getId))));
		Map<Boolean, Optional<Person>> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.minBy(Comparator.comparing(Person::getId))));
4,mapping方法会将一个函数应用到downstream结果上,并且需要另一个收集器来处理结果,代码如下:
Map<Boolean, Optional<String>> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.mapping(Person::getId, Collectors.minBy(Comparator.comparing(String::length)))));
5,reducing方法会对downstream元素进行一次普通的聚合操作,代码如下:
Map<Boolean, Optional<Person>> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.reducing((a, b) -> b)));

总结:
downstream收集器可以产生非常复杂的表达式。我们只有在为了通过groupingBy或者partitoningBy来产生“dowmstream”map时,才使用它们。其他情况下,只需要对流直接应用map,reduce,count,max或者min方法即可。

以下是一份大致的MapReduce编程开发-分组排序的实训报告,同时也提供了相关的重要代码示例,希望能够帮助您了解MapReduce的实践和应用。 一、引言 MapReduce是一种分布式计算框架,它可以将大规模的数据集分成小块,并在多台计算机上进行并行处理。MapReduce框架由Google首先提出,后来Apache Hadoop将其开源,成为了目前最行的分布式计算框架之一。 本次实训的主题是MapReduce的编程开发-分组排序。分组排序是MapReduce中的一个重要操作,它可以将数据集按照键值进行分组,并在每组内按照指定条件进行排序。在实际应用中,分组排序可以用于很多场景,例如用户行为分析、数据挖掘等。 本次实训将分为三个部分:第一部分将介绍MapReduce的基本概念和编程模型;第二部分将介绍MapReduce分组排序的原理和实现方法;第三部分将介绍MapReduce分组排序的实践应用,包括用户行为分析和数据挖掘。 二、MapReduce的基本概念和编程模型 1. MapReduce的基本概念 MapReduce框架由两个关键步骤组成:Map和Reduce。Map操作将输入数据转换为键值对,Reduce操作将键值对按照键分组,并对每组进行操作。 具体来说,Map操作将输入数据划分为多个小块,然后对每个小块进行处理。Map操作的输出是一组键值对,其中每个键值对包含一个键和一个值。Reduce操作将Map操作的输出按照键分组,并对每个组进行操作。Reduce操作的输出也是一组键值对,其中每个键值对包含一个键和一个值。 2. MapReduce的编程模型 MapReduce的编程模型是基于函数式编程的,它将数据处理过程转化为Map和Reduce函数的调用。Map函数将输入数据转换为一组键值对,Reduce函数将键值对按照键分组,并对每组进行操作。 Map函数的输入数据是一个键值对,输出数据也是一个键值对。Reduce函数的输入数据是一个键和一组值,输出数据也是一个键和一组值。 MapReduce编程模型的核心是分布式计算,它将数据处理任务分为若干个小任务,并在多台计算机上进行并行处理。MapReduce框架提供了自动分片、数据并行处理、容错机制等功能,使得开发者可以更加专注于数据处理的逻辑实现,而无需关心底层的分布式计算细节。 三、MapReduce分组排序的原理和实现方法 1. 分组排序的原理 MapReduce分组排序的原理是将数据集按照键值进行分组,然后在每组内按照指定条件进行排序。具体来说,Map函数将输入数据转换为一组键值对,其中键表示分组的依据,值表示需要排序的数据。Reduce函数将键值对按照键分组,并对每个组内的值进行排序操作。 分组排序的实现需要注意以下几点: (1)分组依据必须是可以比较的类型,例如整数、字符串等。 (2)排序条件必须是可以比较的类型,例如整数、浮点数等。 (3)在Reduce函数中进行排序时,需要使用一种高效的排序算法,例如快速排序、归并排序等。 2. 分组排序的实现方法 MapReduce分组排序的实现方法可以分为两种:基于Hadoop API的实现和基于Java API的实现。 基于Hadoop API的实现方法需要使用Hadoop的MapReduce API来编写Map和Reduce函数。具体来说,需要实现Mapper接口和Reducer接口,并对输入输出数据类型进行定义。在Map函数中,需要将输入数据转换为键值对,并将键作为输出的键,值作为输出的值。在Reduce函数中,需要对每个组内的值进行排序,并将排序后的结果作为输出。 以下是基于Hadoop API的MapReduce分组排序的示例代码: ```java public class GroupSort { public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); StringTokenizer tokenizer = new StringTokenizer(line); while (tokenizer.hasMoreTokens()) { word.set(tokenizer.nextToken()); context.write(word, one); } } } public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } context.write(key, new IntWritable(sum)); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = new Job(conf, "groupsort"); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); job.setMapperClass(Map.class); job.setReducerClass(Reduce.class); job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.waitForCompletion(true); } } ``` 基于Java API的实现方法可以使用Java的Map和Reduce函数来编写分组排序程序。具体来说,需要定义一个实现了Comparator接口的类来进行排序操作,并将该类作为Reduce函数的参数。在Map函数中,需要将输入数据转换为键值对,并将键作为输出的键,值作为输出的值。在Reduce函数中,需要对每个组内的值进行排序,并将排序后的结果作为输出。 以下是基于Java API的MapReduce分组排序的示例代码: ```java public class GroupSort { public static class Map extends Map
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值