Java集合架构及排序输出问题
2015-05-02 11:13
288 查看
概述
本文的写作动机来源于博主项目编码实践过程中的一个编码需求:- 如何统计一段文本中的词频并按词频降序输出。
本文针对这一需求给出了三种主要的解决方案:
自定义类Term 并借助于Collections.sort(list, comparator)方法
使用HashMap和Collections.sort(list, comparator)方法
用比较器初始化TreeMap(Comparator)实现
Java集合架构概述
Java集合架构即Collection接口,根据集合论的基本定义,集合(Collection)即为一个存储一组元素(Element)的容器. Java Collection支持三种类型集合,一般书上喜欢翻译成: ’ 规则集(Set)’,’ 线性表(List)’和’ 图(Map)’。博主认为更应该翻译成: ’ 集合(Set)’,’ 线性表(List)’和’ 映射/键值对(Map)’。集合(Set)
按理来说,Set接口才能算是集合论意义上的“集合”,因为Collection中的元素(Element)是可以相同的,而Set接口扩展Collection接口,虽然没有引入任何新的变量和方法,但Set规定了其中的元素(Element)不能重复,即不能存在相同的元素,而元素是否相同由‘equals()’函数定义,Set中不可能同时存在元素 e1和e2, 使得 ‘e1.equals(e2)’。而如果我们将多个相同的元素添加到集合Set中,将只有一个会被存储。集合Set的三个具体类是HashSet,LinkedHashSet和TreeSet.
散列集HashSet
HashSet中的元素是没有特殊顺序的,要给它们排序,需要使用 链式散列集LinkedHashSet 或 树形集TreeSet。链式散列集LinkedHashSet
链式散列集LinkedHashSet 使用链表实现对 HashSet 类的扩展,元素在LinkedHashSet中存储时保持插入的顺序,即在LinkedHashSet中,元素只能按照它们插入LinkedHashSet的顺序进行排序和提取。要实现按照用户自定义的序提取,比如文章一开始提到的按照词频降序,就需要使用树形集TreeSet了。树形集TreeSet
线性表(List)
映射/键值对(Map)
Java集合架构实现词频降序输出
方案一:自定义Term类
该方案首先定义自己的词类Term, 并覆盖比较函数compareTo(Term term):[code]import java.util.Comparator; import java.util.HashMap; import java.util.Map; /** * @author darthy * weibo: http://weibo.com/u/1776952043?wvr=5&lf=reg * 2015-05-02 */ public class Term implements Comparable<Term>{ private String wordName; private int wordCount = 0; // private double wordFreq = 0; // 预留归一化的词频 // private double tfidf = 0; // 预留TF-IDF public Term(){ } public String getWordName(){ return this.wordName; } public void setWordName(String wordName){ this.wordName = wordName; } public int getWordCount(){ return this.wordCount; } public void setWordCount(int wordCount){ this.wordCount = wordCount; } /**实现比较函数*/ @Override public int compareTo(Term o) { if (this.getWordCount() > o.getWordCount()) return 1; // 大于 else if(this.getWordCount() < o.getWordCount()) return -1; // 小于 else return 0; } /** 根据wordCount升序排序的比较器内部类 */ public static class TermComparatorByCount implements Comparator<Term>{ @Override public int compare(Term o1, Term o2) { return o1.compareTo(o2); } } }
然后定义自己的比较器(Comparator)
[code]
最后将文本的Term装入List中,并使用Collections.sort()方法排序
[code]/** Test Main */ public static void main(String[] args) { String text = "have a good day 我是 中文 分词 后 的 文本 以 空格 分隔 统计 中文 and English" + " today is a very sunny day 分词 空格 中文 都 加 一倍 再 加 一个 专利"; text = text.trim(); String[] words = text.split(" "); for ( int i=0; i<words.length; i++){ if (words[i].length() > 1){ if (hashMap.get(words[i]) != null ){ int value = hashMap.get(words[i]).intValue(); // 获取词频 value++; // 词频+1 hashMap.put(words[i], value); // 覆盖添加 } else{ hashMap.put(words[i], 1); } } } ArrayList<Map.Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(); // 存放<String, Integer>对象放入List中 list.addAll(hashMap.entrySet()); MapEntryComparator myComparator = new MapEntryComparator(); // 创建Entry排序器对象 Collections.sort(list, Collections.reverseOrder(myComparator) ); // 使用Entry排序器对list进行排序 }
方案二:使用映射HashMap
首先使用HashMap[code]String text = "have a good day 我是 中文 分词 后 的 文本 以 空格 分隔 统计 中文 and English" + " today is a very sunny day 分词 空格 中文 都 加 一倍 再 加 一个 专利"; text = text.trim(); String[] words = text.split(" "); for ( int i=0; i<words.length; i++){ if (words[i].length() > 1){ if (hashMap.get(words[i]) != null ){ int value = hashMap.get(words[i]).intValue(); // 获取词频 value++; // 词频+1 hashMap.put(words[i], value); // 覆盖添加 } else{ hashMap.put(words[i], 1); } } }
然后定义对键值对Map.Entry
[code]public class MapEntryComparator implements Comparator<Object>{ @Override public int compare(Object o1, Object o2) { Map.Entry<String, Integer> e1 = (Map.Entry<String, Integer>) o1; Map.Entry<String, Integer> e2 = (Map.Entry<String, Integer>) o2; return e1.getValue().compareTo(e2.getValue()); // 按照Integer的正常升序排序 } }
最后将HashMap装入List中,并使用Collections.sort()方法排序
[code]/** Test Main */ public static void main(String[] args) { ArrayList<Map.Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(); // 存放<String, Integer>对象放入List中 list.addAll(hashMap.entrySet()); MapEntryComparator myComparator = new MapEntryComparator(); // 创建Entry排序器对象 Collections.sort(list, Collections.reverseOrder(myComparator) ); // 使用Entry排序器对list进行排序 }
总结
Java集合架构是Java2 新增的非常强大和好用的功能,更多介绍可参考博文 http://blog.sina.com.cn/s/blog_3fb3625f0101aref.html写博不易,转载请注明来源:http://blog.csdn.net/dachylong
若文章存在错误之处,请大家不吝赐教!
相关文章推荐
- Java集合中的排序问题
- java 对集合的排序问题
- Java 集合排序问题
- java集合排序问题
- Java集合中的排序问题
- Java集合中的排序问题
- java语言Collections集合排序问题
- 黑马程序员——JAVA基础--- 集合IO综合练习排序问题
- Java学习-046-日志抓取合并后排序问题解决方案之 --- log4j 二次定制,实现日志输出添加延时10ms
- java 集合排序问题
- 关于java中的List集合的排序问题/Collections.sort()的使用(转)
- Java://Comparator、Comparable的用法(按照要求将set集合的数据进行排序输出):
- java的Map集合中按value值进行排序输出的实例代码
- Java 集合排序、汉字按字母表排序问题
- java程序——用集合框架实现学生类的排序输出
- java集合排序问题
- 集合相等问题(java sort排序数组长度问题)
- Java中的集合存储数据后,输出数据的有序和无序问题
- JDK1.7和1.8中List集合中sort方法排序问题【JAVA】
- 浅谈在java中list集合的排序问题