场景: 需要统计errorMsg的数量, 从大到小排序。 errorMsg为key, 数量为value。
按照key排序 很简单,TreeMap就ok。
按值排序就相对麻烦些了,貌似没有直接可用的数据结构能处理类似需求,需要我们自己转换一下。
Map本身按值排序是很有意义的,很多场合下都会遇到类似需求,可以认为其值是定义的某种规则或者权重。
原理:将待排序Map中的所有元素置于一个列表中,接着使用Collections的一个静态方法 sort(List<T> list, Comparator<? super T> c)
来排序列表,同样是用比较器定义比较规则。排序后的列表中的元素再依次装入Map,为了肯定的保证Map中元素与排序后的List中的元素的顺序一致,使用了LinkedHashMap数据类型。
package com.tristan;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import com.hp.hpsc.logview.client.LogviewClient;
import com.hp.hpsc.logview.po.Link;
public class TestA {
public static void main(String[] args) throws Exception {
/*
* // linux String file = "/opt/sasuapps/itrc/logs/logview/info.log";
* String folder = "/opt/sasuapps/itrc/logs";
*
* LogviewClient client = new LogviewClient(); List<Link> list =
* client.readDirectory(folder); for (Link link : list) {
* System.out.println(link.getName()); }
*
* LogviewClient client2 = new LogviewClient(); client2.readLog(file);
*/
// now
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String nowS = "2014-03-18";
Date nowD = sdf.parse(nowS);
Calendar nowC = Calendar.getInstance();
nowC.setTime(nowD);
String folder = "/opt/sasuapps/itrc/logs/sp4tsusergroup/main/error";
LogviewClient client = new LogviewClient();
List<Link> list = client.readDirectory(folder);
// check file last modified date
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
List<String> fileList = new ArrayList<String>();
for (Link link : list) {
if (!link.isFolderFlag()) {
String s1 = link.getLastModifiedDate();
Date d1 = sdf1.parse(s1);
Calendar c1 = Calendar.getInstance();
c1.setTime(d1);
Calendar nowMinus2 = Calendar.getInstance();
nowMinus2.setTime(nowD);
nowMinus2.add(Calendar.DATE, -2);
if (c1.after(nowMinus2)) {
System.out.println(link.getName());
fileList.add(link.getUri());
}
}
}
// get the content which match the date like 03/21/2013
SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy");
LogviewClient client2 = new LogviewClient();
List<String> errorList = new ArrayList<String>();
for (String file : fileList) {
InputStream input = client2.loadInputStream(file);
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String temp = "";
while ((temp = br.readLine()) != null) {
if (temp.length() > 10) {
String s1 = temp.substring(0, 10);
Date d1 = null;
try {
d1 = sdf2.parse(s1);
} catch (Exception e) {
continue;
}
Calendar c1 = Calendar.getInstance();
c1.setTime(d1);
Calendar nowMinus2 = Calendar.getInstance();
nowMinus2.setTime(nowD);
nowMinus2.add(Calendar.DATE, -2);
Calendar nowMinus1 = Calendar.getInstance();
nowMinus1.setTime(nowD);
nowMinus1.add(Calendar.DATE, -1);
if (c1.after(nowMinus2) && c1.before(nowC)) {
errorList.add(temp);
}
}
}
br.close();
isr.close();
input.close();
}
// parse error list
List<String> errorMsgList = new ArrayList<String>();
for (String error : errorList) {
int begin = error.indexOf("{");
String s1 = error.substring(begin + 1);
int end = s1.indexOf(":");
s1 = s1.substring(0, end);
errorMsgList.add(s1);
}
// statistics
Map<String, Integer> map = new HashMap<String, Integer>();
for (String temp : errorMsgList) {
Integer count = map.get(temp);
map.put(temp, (count == null) ? 1 : count + 1);
}
//sort
Map<String, Integer> resultMap = sortMapByValue(map);
for (String key : resultMap.keySet()) {
System.out.println(resultMap.get(key) + " : " + key);
}
}
public static Map<String, Integer> sortMapByValue(
Map<String, Integer> oriMap) {
if (oriMap == null || oriMap.isEmpty()) {
return null;
}
List<Map.Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(
oriMap.entrySet());
Collections.sort(entryList, new MapValueComparator());
Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
for(Map.Entry<String, Integer> entry : entryList){
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
}
class MapValueComparator implements Comparator<Map.Entry<String, Integer>> {
@Override
public int compare(Entry<String, Integer> me1, Entry<String, Integer> me2) {
return me2.getValue().compareTo(me1.getValue());
}
}
参考
http://blog.csdn.net/top_code/article/details/8528954