數組轉集合、集合轉數組、字符串數組與int型、long型數組等的轉換以及排序問題

==================類型轉換==================

  在項目中常常會遇到數組轉集合、集合轉數組、數組之間類型轉換等操做

 

1.數組轉集合

爲了實現把一個數組轉換成一個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);

 

2.集合轉數組

(1)錯誤演示

不少人習慣下面用法:

        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轉型規則的問題。

 

(2)正確的作法:(延伸一點直接打印數組打印的是數組的)

最菜雞的作法是:

        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));

結果同上。

 

3.數組轉數組--代碼用到了commons-beanutils包

最多見的就是字符串數組類型轉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

 

 補充:補充一點JVM相關知識

在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傳入一個比較器便可。

 

 1.數組排序

  在使用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(); }
    }

 

2.集合排序

  集合排序與數組相似。

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]

相關文章
相關標籤/搜索