爲了實現把一個數組轉換成一個ArrayList,不少Java程序員會使用以下的代碼:html
String str[] = {"1","2","3"};
List<String> strings = Arrays.asList(str);
Arrays.asList確實會返回一個ArrayList對象,可是該類是Arrays類 中一個私有靜態內部類,而不是常見的java.util.ArrayList類。這個java.util.Arrays.ArrayList類具備 set(),get(),contains()等方法,可是不具備任何添加或移除元素的任何方法。由於該類的大小(size)是固定的。若是添加元素是會報錯的(可是若是轉換後的集合只是用來進行查詢不進行增長元素也能夠這樣轉換):java
String str[] = {"1","2","3"}; List<String> strings = Arrays.asList(str); strings.add("eee");
報錯以下:程序員
Exception in thread "main" java.lang.UnsupportedOperationExceptionapache
at java.util.AbstractList.add(AbstractList.java:148)數組
at java.util.AbstractList.add(AbstractList.java:108)ide
at Test.test1(Test.java:31)spa
at Test.main(Test.java:24)3d
爲了建立出一個真正的ArrayList,代碼應該以下所示:(這種方法建立的集合能夠進行集合的增長)code
String str[] = {"1","2","3"}; List<String> strings = new ArrayList<String>(Arrays.asList(str)); strings.add("4"); System.out.println(strings);
更加高效的代碼以下:htm
String str[] = {"1","2","3"}; List<String> strings = new ArrayList<String>(str.length); Collections.addAll(strings,str); strings.add("4"); System.out.println(strings);
不少人習慣下面用法:
List<String> strings = new ArrayList<String>(); String[] objects = (String[]) strings.toArray();
編譯經過,運行報錯以下:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at Test.test1(Test.java:32)
at Test.main(Test.java:26)
學過JVM的應該知道上面的意思是Object數組不能轉變爲String數組。[表明覺得數組,L表明數組的元素是引用類型,後面是具體的元素類型
對於這個現象咱們能夠這麼解釋:Java中容許向上和向下轉型,可是這個轉型是否成功是根據Java虛擬機中這個對象的類型來實現的。Java虛擬機中保存 了每一個對象的類型。而數組也是一個對象。數組的類型是[Ljava.lang.Object。把[Ljava.lang.Object轉換成 [Ljava.lang.String是顯然不可能的事情,由於這裏是一個向下轉型,而虛擬機只保存了這是一個Object的數組,不能保證數組中的元素 是String的,因此這個轉型不能成功。數組裏面的元素只是元素的引用,不是存儲的具體元素,因此數組中元素的類型仍是保存在Java虛擬機中的。
根據上面的解釋,咱們能夠把這個問題概括到下面這個模型:
Object objs[]=new Object[10]; String strs[]=(String[])objs;
這樣子和剛纔上面編譯錯誤是同樣的。若是咱們修改一下這個代碼,以下:
String strs[]=new String[10]; Object objs[]=strs;
這樣子就能夠編譯經過了。因此這個問題咱們能夠歸結爲一個Java轉型規則的問題。
最菜雞的作法是:
List<String> list = new ArrayList<String>(); list.add("1"); String strings[]=new String[list.size()]; for(int i=0,j=list.size();i<j;i++){ strings[i]=list.get(i); } System.out.println(strings); System.out.println(strings.getClass()); System.out.println(Arrays.toString(strings));
結果:
[Ljava.lang.String;@20724356
class [Ljava.lang.String;
[1]
比較簡便的作法:
List<String> list = new ArrayList<String>(); list.add("1"); String[] strings = new String[list.size()]; list.toArray(strings); System.out.println(strings); System.out.println(strings.getClass()); System.out.println(Arrays.toString(strings));
結果同上。
最多見的就是字符串數組類型轉int、long數組,或者字符串類型轉Integer、Long、Integer型轉int(也就是包裝類型轉原始類型)。
最原始的for循環轉換賦值在這裏就不試了。
數組類型的轉換:
import org.apache.commons.beanutils.ConvertUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class Test { public static void main(String[] args) { String str[] = { "1", "2", "3" }; // 字符串數組轉long數組 long[] str2lon = (long[]) ConvertUtils.convert(str, long.class); System.out.println(str2lon); // 字符串數組轉Long數組 Long[] str2Lon = (Long[]) ConvertUtils.convert(str, Long.class); System.out.println(str2Lon); // 字符串數組轉int數組 int[] str2int = (int[]) ConvertUtils.convert(str, int.class); System.out.println(str2int); // 字符串數組轉Integer數組 Integer[] str2Int = (Integer[]) ConvertUtils.convert(str, Integer.class); System.out.println(str2Int); // int型數組轉爲String數組 String int2Str[] = (String[]) ConvertUtils.convert(str2int, String[].class); System.out.println(int2Str); // Integer型數組轉爲String數組 String Int2Str[] = (String[]) ConvertUtils.convert(str2Int, String[].class); System.out.println(Int2Str); // long型數組轉爲String數組 String lon2str[] = (String[]) ConvertUtils.convert(str2lon, String[].class); System.out.println(lon2str); String Lon2str[] = (String[]) ConvertUtils.convert(str2Lon, String[].class); System.out.println(Lon2str); } }
[J@15a6d5e1
[Ljava.lang.Long;@7c23b1e1
[I@b736a73
[Ljava.lang.Integer;@4651a9e4
[Ljava.lang.String;@1b68dbcd
[Ljava.lang.String;@1367dca
[Ljava.lang.String;@207c5965
[Ljava.lang.String;@43d1068c
關於包裝類型轉原始類,能夠用commons-lang包的ArrayUtils操做,參考:http://www.javashuo.com/article/p-thahcpjv-cx.html
在Java中,任何類型都有class,包括基本數據類型與void。在Java中 [ 表明數組, [[ 表明二維數組。依次類推。
其餘的描述標識符以下:
B---基本數據類型byte
C---基本數據類型char
D---基本數據類型double
F---基本數據類型float
I---基本數據類型int
J---基本數據類型long
S---基本數據類型short
Z---基本數據類型boolean
V---特殊類型void
L---對象類型(也就是引用類型)。例如 Ljava/lang/Object.
須要注意的是八種基本數據類型也有 calss,並且其對應包裝類型有一個TYPE成員變量就是其基本數據類型。特殊類型void也有class。基本類型的數組與引用類型數組也都有class
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
例如:
System.out.println(int.class); System.out.println(Integer.class); System.out.println(Integer.TYPE); System.out.println(Integer[].class); System.out.println(int[].class); System.out.println(void.class);
結果:
int
class java.lang.Integer
int
class [Ljava.lang.Integer;
class [I
void
注意int不是對象,因此沒有getClass方法。只有int.class
JDK自帶的排序方法能夠知足大部分要求。咱們知道要在集合中排序,須要使用能夠排序的集合或者本身手動排序。使用可排序的集合如TreeMap,TreeSet。若是手動排序就是用Collections.sort傳入一個比較器便可。
在使用Arrays.sort()對int、double、long等基本類型的數組進行排序時,只有正序排序的方法。要實現倒序排序,只有使用Integer、Double、Long等代替。
包裝類型比較的時候能夠傳入比較器,以下:
import java.util.Arrays; import java.util.Collections; import java.util.Comparator; public class PlainTest { public static void main(String[] args) { // 基本數據類型Arrays.sort正序 char[] chars = { 'a', 'b', 'd', 'e', 'c', 'e', 'd', 'a' }; Arrays.sort(chars); System.out.println(chars); // 原生數組正序 Character[] characters = { 'a', 'b', 'd', 'e', 'c', 'e', 'd', 'a' }; Arrays.sort(characters); System.out.println(Arrays.toString(characters)); // 原生數組逆序 Arrays.sort(characters, Collections.reverseOrder()); System.out.println(Arrays.toString(characters)); // 本身實現逆序號排序 Arrays.sort(characters, new Comparator<Character>() { @Override public int compare(Character o1, Character o2) { if (o1 > o2) { return -1; } else if (o1 < o2) { return 1; } return 0; } }); System.out.println(Arrays.toString(characters)); } }
結果:
aabcddee
[a, a, b, c, d, d, e, e]
[e, e, d, d, c, b, a, a]
[e, e, d, d, c, b, a, a]
查看源碼:(逆序是經過反轉compare來實現的)
public static <T> Comparator<T> reverseOrder() { return (Comparator<T>) ReverseComparator.REVERSE_ORDER; } private static class ReverseComparator implements Comparator<Comparable<Object>>, Serializable { private static final long serialVersionUID = 7207038068494060240L; static final ReverseComparator REVERSE_ORDER = new ReverseComparator(); public int compare(Comparable<Object> c1, Comparable<Object> c2) { return c2.compareTo(c1); } private Object readResolve() { return reverseOrder(); } }
集合排序與數組相似。
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class PlainTest { public static void main(String[] args) { Character[] characters = { 'a', 'b', 'd', 'e', 'c', 'e', 'd', 'a' }; List<Character> list = new ArrayList<Character>(Arrays.asList(characters)); System.out.println(list); // 集合正序 Collections.sort(list); System.out.println(list); // 集合逆序 Collections.sort(list, Collections.reverseOrder()); System.out.println(list); // 本身實現逆序號排序 Collections.sort(list, new Comparator<Character>() { @Override public int compare(Character o1, Character o2) { if (o1 > o2) { return -1; } else if (o1 < o2) { return 1; } return 0; } }); System.out.println(list); } }
結果:
[a, b, d, e, c, e, d, a][a, a, b, c, d, d, e, e][e, e, d, d, c, b, a, a][e, e, d, d, c, b, a, a]