Java 常见类型转换
环境:jdk8
在常用的方法中添加了下划线。
Array to List/Set
Arrays.asList
List<Integer> list = Arrays.asList(new Integer[]{1, 2, 3});
// 可简写为
List<Integer> list = Arrays.asList(1, 2, 3);
注意一:不能写成如下形式,即使用 int[]
作为参数。
List<Integer> list = Arrays.asList(new int[]{1, 2, 3});
因为 Arrays.asList
需要传入 T... a
(变长参数),即传入对象或对象数组。若传入 int[]
作为参数,返回类型将为 List<int[]>
。
注意二:得到的集合实际上是 java.util.Arrays.ArrayList
,即 Arrays
的私有静态内部类,而不是 java.util.ArrayList
。java.util.Arrays.ArrayList
类具有 set()
、get()
、contains()
方法,但是没有 add()
或 remove()
方法。即不能对其进行增删,只能修改和查询。
同时,对原数组的修改会同时改变获得的 List
。
(Arrays.asList
的作用更像是将 Array
包装起来使其看起来像一个 List
)
若想进一步得到可变集合,可以使用:
Set set = new HashSet(Arrays.asList(array));
或
List list = new ArrayList(Arrays.asList(array));
Collections.addAll
List<Integer> list = new ArrayList<>();
Collections.addAll(list, new Integer[]{1, 2, 3});
// 可简写为
Collections.addAll(list, 1, 2, 3);
// 也可以用于 Set,此处略
注意一:同 Arrays.asList
的注意一,即不能传入 int[]
作为参数。
Collections.addAll(new ArrayList<Integer>(), new int[]{1, 2, 3});
List/Set to Array
list.toArray
此处主要参考廖雪峰的 Java 教程
list.toArray
有两个重载的方法:
Object[] toArray()
<T> T[] toArray(T[] a)
第一种方法会返回 Object[]
,丢失类型信息,所以实际应用很少。
第二种方法源码如下:
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
如果传入的数组不够大,那么 List
内部会创建一个新的刚好够大的数组,填充后返回;如果传入的数组比 List
元素还要多,那么填充完元素后,剩下的数组元素一律填充 null
。
常见使用方法如下:
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
// 直接传入一个与 list 大小相等的数组
Integer[] array = list.toArray(new Integer[list.size()]);
List and Set
addAll
方法签名为:addAll(Collection<? extends E> c)
。
同时 List
和 Set
都实现了 Collection
接口,所以可以采用如下方法进行转换。
// List 转 Set
List<Integer> list = new ArrayList<>();
Set<Integer> set = new HashSet<>();
set.addAll(list);
constructor
ArrayList
和 HashSet
也都提供了 Collection<? extends E> c
作为参数的构造函数。(实际上,底层调用的就是 addAll
)
可以直接使用构造函数的形式完成互相转化。
// Set 转 List
List<Integer> list = new ArrayList<>(new HashSet<>());
// List 转 Set
Set<Integer> set = new HashSet<>(new ArrayList<>());
char[] to String
constructor
构造函数签名:String(char value[])
char[] charArr = {'a', 'b', 'c'};
String s = new String(charArr);
String.valueOf
char[] charArr = {'a', 'b', 'c'};
String s = String.valueOf(charArr);
实际上底层调用的还是 String
的构造函数。
String to char[]
s.toCharArray
String s = "abc";
char[] charArr = s.toCharArray();
byte[] to String
constructor
byte[] bs = {116, 101, 115, 116, 49, 50, 51};
// 不推荐直接转换,而是应该指定编码格式
String s = new String(bs); // test123
// 指定编码格式的方法
// 方法一:推荐
new String(bs, StandardCharsets.UTF_8);
// 方法二:不推荐(需要使用 try/catch 来捕获 UnsupportedEncodingException 异常)
new String(bs, "utf8");
/* 以下几种都可以识别成 utf-8
new String(bs, "UTF-8");
new String(bs, "uTf8");
new String(bs, "UtF-8");
*/
String to byte[]
s.getByte
String s = "test123";
// 不推荐直接转换,而是应该指定编码格式
byte[] bs = s.getBytes();
// 指定编码格式的方法
// 方法一:推荐
s.getBytes(StandardCharsets.UTF_8);
// 方法二:不推荐(需要使用 try/catch 来捕获 UnsupportedEncodingException 异常)
s.getBytes("utf-8");
int to String
+ ""
String s = 123 + "";
不推荐。效率低,本质上是新建了 StringBuilder
对象。
String.valueOf
String s = String.valueOf(123);
实际上是调用了接下来的 Integer.toString
。
Integer.toString
String s = Integer.toString(123);
String to int
Integer.parseInt
int i = Integer.parseInt("123");
转换内容格式错误(如超过整型范围、含有字母、特殊字符等)会抛出 NumberFormatException
。
Integer.valueOf
Integer integer = Integer.valueOf("123");
int i = integer.intValue();
// 也可以使用自动拆箱
int i = Integer.valueOf("123");
实际上在底层调用了 parseInt
。
public static Integer valueOf(String s) throws NumberFormatException { return Integer.valueOf(parseInt(s, 10)); }