讨论组12.20讲述内容笔记
2015-12-21 09:45
309 查看
介绍java.util.BitSet
BitSet 类创建一个特殊类型的数组保存位值。该BitSet中数组的大小可以根据需要增加。
1.构造函数
2.set方法
3.hashcode
4.size() length()
用途:
存储海量数据:
一个int占4个字节。
比如有一堆数字,需要存储,source=[3,5,6,9],用int就需要4*4个字节。
java.util.BitSet可以存true/false。
如果用java.util.BitSet,则会少很多:
1,先找出数据中最大值maxvalue=9
2,声明一个BitSet bs,它的size是maxvalue+1=10
3,遍历数据source,bs[source[i]]设置成true.
这样一个本来要int型需要占4字节共32位的数字现在只用了1位,比例32:1
BloomFilter:
1、用MapReduce找共同朋友编程实现
数据格式如下:
第一个字母代表本人,其他是他的朋友,找出共同朋友的人,和共同朋友是谁?
2、一个很大的2D矩阵,如果某点的值,由它周围某些点的值决定,例如下一时刻(i,j) 的值取当前时刻它的8邻点的平均,那么怎么用MapReduce来实现。
以下标对作为map的key,遇到(i,j),生成(i-1,j-1),(i-1,j),etc,然后在reduce时merge相同的key,并计算value。
讨论题:3、现有100万酒店坐标和20亿地标,里面记录地标的经纬度,请设计mapreduce计算所有酒店1公里范围内的地标。
假设酒店坐标和地标坐标都在一个文件,假设字段为
类型(酒店/地标) id(酒店id/地标id) 纬度 经度
BitSet 类创建一个特殊类型的数组保存位值。该BitSet中数组的大小可以根据需要增加。
1.构造函数
private long[] words; private final static int ADDRESS_BITS_PER_WORD = 6; public BitSet(int nbits) { // nbits can't be negative; size 0 is OK if (nbits < 0) throw new NegativeArraySizeException("nbits < 0: " + nbits); initWords(nbits); sizeIsSticky = true; } private void initWords(int nbits) { words = new long[wordIndex(nbits-1) + 1]; // 初始化会根据的位数决定要申请多大的数组,long 类型是 64 位,所以你如果 nbits 是 1~64,你只需要一个长度为1的数组就好。 } private static int wordIndex(int bitIndex) { return bitIndex >> ADDRESS_BITS_PER_WORD; }
2.set方法
public void set(int bitIndex) { if (bitIndex < 0) throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); int wordIndex = wordIndex(bitIndex); expandTo(wordIndex); words[wordIndex] |= (1L << bitIndex); // Restores invariants checkInvariants(); /** 这是在改变long数组的某一个元素的值,首先需要确定的是改变哪一个元素,其次需要使用与或操作改变这个元素,在上面的代码中,首先将bitIndex>>6,这样就确定了是修改哪一个元素的值。 注意: java中的移位操作会模除位数,也就是说,long类型的移位会模除64。例如对long类型的值左移65位,实际是左移了65%64=1位。所以这行代码就等于: int cache = bitIndex % 64; words[wordsIndex] |= (1L << cache); */ }
3.hashcode
public int hashCode() { long h = 1234; for (int i = wordsInUse; --i >= 0; ) h ^= words[i] * (i + 1); return (int)((h >> 32) ^ h); }
4.size() length()
public int size() { return words.length * BITS_PER_WORD; } //BITS_PER_WORD = 64,这里很重要的一点就是,如果使用size来返回BitSet数组的大小,其值一定是64的倍数 public int length() { if (wordsInUse == 0) return 0; return BITS_PER_WORD * (wordsInUse - 1) + (BITS_PER_WORD - Long.numberOfLeadingZeros(words[wordsInUse - 1])); } //这个方法法返回的是BitSet的逻辑大小,比如说你声明了一个129位的BitSet,设置了第23,45,67位,那么其逻辑大小就是67。
用途:
存储海量数据:
一个int占4个字节。
比如有一堆数字,需要存储,source=[3,5,6,9],用int就需要4*4个字节。
java.util.BitSet可以存true/false。
如果用java.util.BitSet,则会少很多:
1,先找出数据中最大值maxvalue=9
2,声明一个BitSet bs,它的size是maxvalue+1=10
3,遍历数据source,bs[source[i]]设置成true.
这样一个本来要int型需要占4字节共32位的数字现在只用了1位,比例32:1
BloomFilter:
import org.apache.hadoop.io.Writable; class BloomFilter<E> implements Writable { private BitSet bf; private int bitArraySize = 100000000; private int numHashFunc = 6; public BloomFilter() { bf = new BitSet(bitArraySize); } public void add(E obj) { int[] indexes = getHashIndexes(obj); for (int index : indexes) { bf.set(index); } } public boolean contains(E obj) { int[] indexes = getHashIndexes(obj); for (int index : indexes) { if (bf.get(index) == false) { return false; } } return true; } public void union(BloomFilter<E> other) { bf.or(other.bf); } protected int[] getHashIndexes(E obj) { int[] indexes = new int[numHashFunc]; long seed = 0; byte[] digest; try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(obj.toString().getBytes()); digest = md.digest(); for (int i = 0; i < 6; i++) { seed = seed | (((long)digest[i] & 0xFF))<<(8*i); } } catch (NoSuchAlgorithmException e) {} Random gen = new Random(seed); for (int i = 0; i < numHashFunc; i++) { indexes[i] = gen.nextInt(bitArraySize); } return indexes; } }
1、用MapReduce找共同朋友编程实现
数据格式如下:
第一个字母代表本人,其他是他的朋友,找出共同朋友的人,和共同朋友是谁?
public class FindFriend { final static String INPUT_PATH = "hdfs://master:8020/liguodong/test1"; final static String OUTPUT_PATH = "hdfs://master:8020/liguodong/test1out"; public static void main(String[] args) throws IOException, URISyntaxException, ClassNotFoundEx b5f7 ception, InterruptedException { Configuration conf = new Configuration(); final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH),conf); if(fileSystem.exists(new Path(OUTPUT_PATH))) { fileSystem.delete(new Path(OUTPUT_PATH),true); } Job job = Job.getInstance(conf,"Find friend"); job.setJarByClass(FindFriend.class); job.setMapperClass(MyMapper.class); job.setReducerClass(MyReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); FileInputFormat.addInputPath(job, new Path(INPUT_PATH)); FileOutputFormat.setOutputPath(job,new Path(OUTPUT_PATH)); System.exit(job.waitForCompletion(true)?0:1); } static class MyMapper extends Mapper<LongWritable,Text,Text,Text>{ protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { //分割字符串 StringTokenizer stringTokenizer = new StringTokenizer(value.toString()); Text owner = new Text();//存放自己 Set<String> set = new TreeSet<String>();//存放朋友 owner.set(stringTokenizer.nextToken()); while(stringTokenizer.hasMoreTokens()){ set.add(stringTokenizer.nextToken()); } String[] friends = new String[set.size()];//朋友 friends = set.toArray(friends); for(int i=0; i<friends.length;i++){ for(int j=i+1; j<friends.length; j++){ String outputkey = friends[i]+friends[j];//朋友之间两两组合 context.write(new Text(outputkey), owner);//<朋友组合,自己> } } } } static class MyReducer extends Reducer<Text, Text ,Text, Text> { protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { //以朋友组合作为key值,自己作为value值。 String commonFriends = ""; for(Text val:values) { if(commonFriends == ""){ commonFriends = val.toString(); }else{ commonFriends = commonFriends+"--"+val.toString(); } } context.write(key, new Text(commonFriends)); } } }
2、一个很大的2D矩阵,如果某点的值,由它周围某些点的值决定,例如下一时刻(i,j) 的值取当前时刻它的8邻点的平均,那么怎么用MapReduce来实现。
以下标对作为map的key,遇到(i,j),生成(i-1,j-1),(i-1,j),etc,然后在reduce时merge相同的key,并计算value。
讨论题:3、现有100万酒店坐标和20亿地标,里面记录地标的经纬度,请设计mapreduce计算所有酒店1公里范围内的地标。
假设酒店坐标和地标坐标都在一个文件,假设字段为
类型(酒店/地标) id(酒店id/地标id) 纬度 经度
相关文章推荐
- Hadoop_2.1.0 MapReduce序列图
- MongoDB中的MapReduce简介
- MongoDB学习笔记之MapReduce使用示例
- MongoDB中MapReduce编程模型使用实例
- MapReduce中ArrayWritable 使用指南
- Java函数式编程(七):MapReduce
- java连接hdfs ha和调用mapreduce jar示例
- 用PHP和Shell写Hadoop的MapReduce程序
- JavaScript mapreduce工作原理简析
- mongodb mapredReduce 多个条件分组(group by)
- HBase基本原理
- HDFS DatanodeProtocol——sendHeartbeat
- HDFS DatanodeProtocol——register
- Hadoop集群提交作业问题总结
- Hadoop源码分析 HDFS ClientProtocol——addBlock
- Hadoop源码分析HDFS ClientProtocol——create
- Hadoop源码分析FSNamesystem几个重要的成员变量
- Hadoop源码分析HDFS ClientProtocol——getBlockLocations
- Hadoop源码分析HDFS Client向HDFS写入数据的过程解析
- ZooKeeper基本理解