`

java 相关问题(四)

    博客分类:
  • java
 
阅读更多

十九、Java中对Map(HashMap,TreeMap,Hashtable等)的排序

首先简单说一下他们之间的区别:

HashMap: 最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非同步的。

TreeMap: 能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。

Hashtable: 与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。

LinkedHashMap: 保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。

TreeMap默认按key进行升序排序,如果想改变默认的顺序,可以使用比较器:

Map<String,String> map = new TreeMap<String,String>(new Comparator<String>(){
   public int compare(String obj1,String obj2){
    //降序排序
    return obj2.compareTo(obj1);
   }
  });
  map.put("month", "The month");
  map.put("bread", "The bread");
  map.put("attack", "The attack");
 
  Set<String> keySet = map.keySet();
  Iterator<String> iter = keySet.iterator();
  while(iter.hasNext()){
   String key = iter.next();
   System.out.println(key+":"+map.get(key));
  }

 

如果要对 TreeMap 按照 value 的值进行排序,或者对 HashMap,Hashtable,LinkedHashMap 进行排序,则可以使用 Map.Entry<K,V> 接口结合List实现:

 

    eg.1 对TreeMap按照value值升序:

   

List<Map.Entry<String,String>> mappingList = null;
  Map<String,String> map = new TreeMap<String,String>();
  map.put("aaaa", "month");
  map.put("bbbb", "bread");
  map.put("ccccc", "attack");
 
  //通过ArrayList构造函数把map.entrySet()转换成list
  mappingList = new ArrayList<Map.Entry<String,String>>(map.entrySet());
  //通过比较器实现比较排序
  Collections.sort(mappingList, new Comparator<Map.Entry<String,String>>(){
   public int compare(Map.Entry<String,String> mapping1,Map.Entry<String,String> mapping2){
    return mapping1.getValue().compareTo(mapping2.getValue());
   }
  });
 
  for(Map.Entry<String,String> mapping:mappingList){
   System.out.println(mapping.getKey()+":"+mapping.getValue());
  }

 

    eg.2 对HashMap(或Hashtable,LinkedHashMap)按照key的值升序:

   

List<Map.Entry<String,String>> mappingList = null;
  Map<String,String> map = new HashMap<String,String>();
  map.put("month", "month");
  map.put("bread", "bread");
  map.put("attack", "attack");
 
  //通过ArrayList构造函数把map.entrySet()转换成list
  mappingList = new ArrayList<Map.Entry<String,String>>(map.entrySet());
  //通过比较器实现比较排序
  Collections.sort(mappingList, new Comparator<Map.Entry<String,String>>(){
   public int compare(Map.Entry<String,String> mapping1,Map.Entry<String,String> mapping2){
    return mapping1.getKey().compareTo(mapping2.getKey());
   }
  });
 
  for(Map.Entry<String,String> mapping:mappingList){
   System.out.println(mapping.getKey()+":"+mapping.getValue());
  } 

 

 

二十、Java 中  BigDecimal 的相关用法

    1.BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 方法  

    BigDecimal   b   =   new   BigDecimal(“10.01”);
    b.divide(1,2,4)
     1 表示除以 1
     2 表示2位小数
     4 是BigDecimal.ROUND_HALF_UP,也就是最常见的四舍五入,大于一般则向上舍入,否则向下舍入

 

     2.  java中的BigDecimal和String的相互转换

//数字字符串
String StrBd="1048576.1024";
//构造以字符串内容为值的BigDecimal类型的变量bd
BigDecimal bd=new BigDecimal(StrBd);
//设置小数位数,第一个变量是小数位数,第二个变量是取舍方法(四舍五入)
bd=bd.setScale(2, BigDecimal.ROUND_HALF_UP);
//转化为字符串输出
String OutString=bd.toString();

 

    3.  java中的 BigDecimal加减乘除运算

package test1;

import java.math.BigDecimal;

/**
 * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。
 */
public class Arith { // 默认除法运算精度
    private static final int DEF_DIV_SCALE = 10; // 这个类不能实例化

    private Arith() {
    }

    /**
     * 提供精确的加法运算。
     * 
     * @param v1
     *            被加数
     * @param v2
     *            加数
     * @return 两个参数的和
     */
    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     * 
     * @param v1
     *            被减数
     * @param v2
     *            减数
     * @return 两个参数的差
     */
    public static double sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算。
     * 
     * @param v1
     *            被乘数
     * @param v2
     *            乘数
     * @return 两个参数的积
     */
    public static double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
     * 
     * @param v1
     *            被除数
     * @param v2
     *            除数
     * @return 两个参数的商
     */
    public static double div(double v1, double v2) {
        return div(v1, v2, DEF_DIV_SCALE);
    }

    /**
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
     * 
     * @param v1
     *            被除数
     * @param v2
     *            除数
     * @param scale
     *            表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理。
     * 
     * @param v
     *            需要四舍五入的数字
     * @param scale
     *            小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}

 

 

 

二十一、Java ,JSON 之间互相转换

jackson-databind-2.2.1.jar

jackson-annotations-2.2.1.jar

jackson-core-2.2.1.jar

jackson-mapper-asl-1.9.13.jar

jackson-core-asl-1.9.13.jar

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;

public class JsonUtil {

	private static ObjectMapper mapper = new ObjectMapper(); // can reuse, share
																// globally
	static {
		mapper.configure(
				DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}

	/**
	 * 把 java 对象转化为 json 对象
	 */
	public static <T> String java2json(T t) {
		String json = null;
		try {
			json = mapper.writeValueAsString(t); // 把 java 对象转化为 json 对象
		} catch (JsonGenerationException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (JsonMappingException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (IOException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		}

		return json;
	}

	/**
	 * 把 json 对象转化为 java 对象
	 * 
	 */
	public static <T> T json2java(String json, Class<T> valueType) {
		T obj = null;
		try {
			obj = mapper.readValue(json, valueType); // 把 json 对象转化为 java 对象
			// User user = mapper.readValue(json, User.class); // 把 json 对象转化为
			// java 对象
		} catch (JsonGenerationException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (JsonMappingException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (IOException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		}

		return obj;
	}

	public static <T> List<T> json2javaList(String json, Class<T> valueType) {
		List<T> obj = null;
		try {
			JavaType javaType = mapper.getTypeFactory()
					.constructParametricType(ArrayList.class, valueType);

			//解决不能反序列化
			mapper.configure(
					DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY,
					true);
			obj = mapper.readValue(json, javaType); // 把 json 对象转化为 java 对象
		} catch (JsonGenerationException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (JsonMappingException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		} catch (IOException ex) {
			Logger.getLogger(JsonUtil.class.getName()).log(Level.SEVERE, null,
					ex);
		}
		return obj;
	}

	/**
	 * 打印map
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void printMap(Map map) {
		Set<String> keySet = map.keySet();
		for (String key : keySet) {
			System.out.println("key = " + key);
			Object obj = map.get(key);

			String className = obj.getClass().getName();
			System.out.println("type =" + className);

			boolean isMap = className.toLowerCase().indexOf("map") >= 0;
			boolean isList = className.toLowerCase().indexOf("list") >= 0;

			if (isMap) {
				System.out.println("==== is map ====");
				printMap((Map) obj); // 递归调用
			} else if (isList) {
				List list = (List) obj;
				System.out.println("==== is list ==== , size = " + list.size());
				for (Object oo : list) {
					System.out.println("element type ="
							+ oo.getClass().getName());
					System.out.println("element toString =" + oo.toString());
				}
			} else {
				System.out.println("obj.toString = " + obj.toString());
			}
		}
	}
}

 

 

 

二十二、Arrays.asList() 的bug

常常使用Arrays.asLisvt()后调用add,remove这些method时出现java.lang.UnsupportedOperationException异常。这是由于:

Arrays.asList() 返回java.util.Arrays$ArrayList, 而不是ArrayList。Arrays$ArrayList和ArrayList都是继承AbstractList,remove,add等method在AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。ArrayList override这些method来对list进行操作,但是Arrays$ArrayList没有override remove(int),add(int)等,所以throw UnsupportedOperationException。

解决方法是使用Iterator,或者转换为ArrayList

List list = Arrays.asList(a[]);
List arrayList = new ArrayList(list); 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

Global site tag (gtag.js) - Google Analytics