Java中Array、List、Map相互轉(zhuǎn)換的方法詳解
引言
在實(shí)際項(xiàng)目開發(fā)中或者一些算法面試題目中經(jīng)常需要用到Java中這三種類型的相互轉(zhuǎn)換,比如對(duì)于一個(gè)整型數(shù)組中尋找一個(gè)整數(shù)與所給的一個(gè)整數(shù)值相同,正常情況下第一反應(yīng)會(huì)想到用for循環(huán)直接遍歷這個(gè)數(shù)組就可以實(shí)現(xiàn),不過(guò)這種情況下時(shí)間復(fù)雜度將會(huì)是O(n),空間復(fù)雜度是O(1)。
如果再多加幾個(gè)條件還使用多層for循環(huán)嵌套的話也可以實(shí)現(xiàn),不過(guò)時(shí)間復(fù)雜度將會(huì)以指數(shù)級(jí)增長(zhǎng)。
我們可以說(shuō)多層for循環(huán)嵌套可以實(shí)現(xiàn)功能,但就執(zhí)行時(shí)間來(lái)說(shuō),它絕不會(huì)是一個(gè)好的解決方法。那么如何降低時(shí)間復(fù)雜度呢,這個(gè)時(shí)候我們可以考慮一下將這個(gè)整型數(shù)組轉(zhuǎn)換為一個(gè)Map,因?yàn)镸ap是以key,value鍵值對(duì)形式存儲(chǔ),value允許重復(fù),但是key不允許重復(fù)。
使用Map中map.containsKey()方法可以輕松實(shí)現(xiàn)對(duì)于key是否存在一個(gè)值的查找,此種方法時(shí)間復(fù)雜度為O(1),空間復(fù)雜度為O(n),其中 n是數(shù)組中的元素?cái)?shù)量,主要為哈希表的開銷。
這就降低了方法的執(zhí)行時(shí)間,算是一種算法上的優(yōu)化。
補(bǔ)充
一個(gè)好的算法要求正確性、可讀性、健壯性、時(shí)間效率高而且空間使用率低、簡(jiǎn)單性。
算法的復(fù)雜度分為時(shí)間復(fù)雜度和空間復(fù)雜度。
時(shí)間復(fù)雜度:
時(shí)間復(fù)雜度實(shí)際上是一個(gè)函數(shù),代表基本操作重復(fù)執(zhí)行的次數(shù),進(jìn)而分析函數(shù)雖變量的變化來(lái)確定數(shù)量級(jí),數(shù)量級(jí)用O表示,如O(1),O(n),O(n^2)等。
空間復(fù)雜度:
是對(duì)一個(gè)算法在運(yùn)行過(guò)程中臨時(shí)占用存儲(chǔ)空間的度量,一個(gè)算法在計(jì)算機(jī)存儲(chǔ)器上所占用的存儲(chǔ)空間包括存儲(chǔ)算法本身所占用的空間,算數(shù)和輸入輸出所占用的存儲(chǔ)空間以及臨時(shí)占用存儲(chǔ)空間三個(gè)部分,算法的輸入輸出數(shù)據(jù)所占用的存儲(chǔ)空間是由待解決的問(wèn)題來(lái)決定的,通過(guò)參數(shù)表由調(diào)用函數(shù)而來(lái),它隨本算法的不同而改變,存儲(chǔ)算法本身所占用的存儲(chǔ)空間有算法的書寫長(zhǎng)短成正比。算法在運(yùn)行過(guò)程中占用的臨時(shí)空間由不同的算法決定。
時(shí)間復(fù)雜度與空間復(fù)雜度沒(méi)有必然聯(lián)系,但是也有以空間換時(shí)間或時(shí)間換空間,現(xiàn)今項(xiàng)目中一般要求效率,大部分需要降低執(zhí)行時(shí)間即降低時(shí)間復(fù)雜度,以空間換時(shí)間來(lái)提高效率。不過(guò)在這兩者之間取舍需要具體問(wèn)題具體分析。
正文:
Array轉(zhuǎn)List:
有兩種方法可以將array轉(zhuǎn)為list,一種是使用Arrays.asList()方法直接轉(zhuǎn)換,不過(guò)此種方法的list長(zhǎng)度固定,無(wú)法進(jìn)行添加刪除操作。
另一種是使用for循環(huán)遍歷數(shù)組元素逐個(gè)添加進(jìn)一個(gè)空的list中。
/** * 方法一:使用Arrays.asList()方法將數(shù)組轉(zhuǎn)為list,不過(guò)此種方法有限制,返回的對(duì)象是Arrays的內(nèi)部類 * 對(duì)于轉(zhuǎn)換后的list操作仍然反映在原數(shù)組上,因此這個(gè)list是定長(zhǎng)的,無(wú)法使用list的add()喝remove()方法 */ public static void array_list(String[] array){ List<String> list = Arrays.asList(array); System.out.println("數(shù)組轉(zhuǎn)List 的第一種方法:"+list); // list.remove("李四"); // list.add("劉六"); // System.out.println(“修改后:”list); }
/** * 方法二:正常情況下array轉(zhuǎn)換為list,使用for循環(huán)將數(shù)組中的元素逐個(gè)添加到一個(gè)空的list中 */ public static void array_list2(String[] array){ List<String> list = new ArrayList<>(); for (int i=0;i<array.length;i++){ list.add(array[i]); } System.out.println("數(shù)組轉(zhuǎn)List 的第二種方法:"+list); list.remove("李四"); list.add("劉六"); System.out.println("修改后:"+list); }
List轉(zhuǎn)為Array:
使用list.toArray()將List直接轉(zhuǎn)換為Array
//List轉(zhuǎn)Array public static void list_array(List<String> list){ String[] array =list.toArray(new String[list.size()]); System.out.println("List轉(zhuǎn)數(shù)組:"+array); }
Array轉(zhuǎn)Map:
當(dāng)數(shù)組是一維數(shù)組時(shí),奇數(shù)位是key鍵,偶數(shù)位是value值。數(shù)組有奇數(shù)個(gè)元素時(shí),舍棄最后一個(gè)元素。
//Array轉(zhuǎn)Map /** *一維數(shù)組時(shí),奇數(shù)位為key鍵,偶數(shù)位為value,如果有奇數(shù)個(gè)元素,最后一個(gè)舍掉 */ public static void array_map(String[] array) { Map map = MapUtils.putAll(new HashMap(),array); System.out.println("數(shù)組轉(zhuǎn)Map:"+map); }
當(dāng)數(shù)組是二維數(shù)組時(shí),可以看作兩個(gè)一維數(shù)組,使用ArrayUtils.toMap()方法轉(zhuǎn)換
/** * 二維數(shù)組時(shí),當(dāng)成兩個(gè)一維數(shù)組,使用ArrayUtils.toMap()方法轉(zhuǎn)換 */ public static void array_map2(String[][] array2){ Map map2 = ArrayUtils.toMap(array2); map2.put("南昌","江西"); System.out.println("二維數(shù)組轉(zhuǎn)Map:"+map2); }
Map轉(zhuǎn)Array
Map只需要value值時(shí),將Map的values轉(zhuǎn)為一維數(shù)組:
使用map.values().toArray()方法將map轉(zhuǎn)為object類型的數(shù)組,特定類型數(shù)組需要再次轉(zhuǎn)換。
//Map轉(zhuǎn)Array /** *Map只需要value值時(shí),將Map的values轉(zhuǎn)為一維數(shù)組 *使用map.values().toArray()將map轉(zhuǎn)為object數(shù)組,如果想要轉(zhuǎn)為特定類型的數(shù)組需要再進(jìn)一步轉(zhuǎn)換 */ public static void map_array(Map<Integer,String> map){ Object[] obj = map.values().toArray(); /** * 第一種,使用Arrays.copyOf()方法將原數(shù)組內(nèi)的元素拷貝到一個(gè)新的String類型的數(shù)組 * Arrays.copyOf(原數(shù)組,復(fù)制的長(zhǎng)度,指定轉(zhuǎn)換的類型) */ String[] array = Arrays.copyOf(obj,obj.length,String[].class); System.out.println("Map轉(zhuǎn)Array的第一種方法:"+array); /** * 第二種方法,直接強(qiáng)制轉(zhuǎn)換數(shù)組為指定類型 * 此處toArray()中的參數(shù)需要一個(gè)T[] a,new String[0]相當(dāng)于開辟了一個(gè)長(zhǎng)度為0的String[],并且指定了泛型。 * 這里的用new String[0]只是為了指定函數(shù)的形參數(shù),最終返回的String[]的長(zhǎng)度是由你的list存儲(chǔ)內(nèi)容的長(zhǎng)度決定了。 * new String[0]就是起一個(gè)模板的作用,指定了返回?cái)?shù)組的類型,0是為了節(jié)省空間,因?yàn)樗皇菫榱苏f(shuō)明返回的類型。 * 因此list.toArray()方法中的參數(shù)也可以使用String[0]來(lái)指代 */ String[] array2 =map.values().toArray(new String[0]); System.out.println("Map轉(zhuǎn)Array的第二種方法:"+array2); /** * 第三種方法,使用Java8中Arrays.stream()方法,將對(duì)象數(shù)組轉(zhuǎn)為順序Stream,然后使用toArray方法將流的元素累積到新的字符串?dāng)?shù)組中 * String[]::new 是Java8中新定義的一種寫法叫做方法引用,以下這種寫法是調(diào)用了構(gòu)造器引用,為了生成一個(gè)String類型數(shù)組 */ String[] array3 = Arrays.stream(obj).toArray(String[]::new); System.out.println("Map轉(zhuǎn)Array的第三種方法:"+array3); }
Map需要保留key與value時(shí),將Map轉(zhuǎn)為二維數(shù)組:
/** * 第二種:使用for循環(huán)和迭代器遍歷這個(gè)map,將它的key與value逐個(gè)添加到一個(gè)定長(zhǎng)的二維數(shù)組中 */ public static void map_array2(Map<Integer,String> map){ if (map!=null && !map.isEmpty()){ //以map的長(zhǎng)度作為二維數(shù)組的長(zhǎng)度,其中每個(gè)元素就是一個(gè)長(zhǎng)度為2的小數(shù)組存放key與value Object[][] obj = new Object[map.size()][2]; /** * map.entrySet()是把HashMap類型的數(shù)據(jù)轉(zhuǎn)換成集合類型 * map.entrySet().iterator()是去獲得這個(gè)集合的迭代器,保存在iterator里面。 */ Iterator iterator = map.entrySet().iterator(); for(int i=0;i<map.size();i++){ Map.Entry entry = (Map.Entry) iterator.next(); Object key = entry.getKey(); Object value = entry.getValue(); obj[i][0] = key; obj[i][1] = value; } System.out.println("Map轉(zhuǎn)為二維數(shù)組Array:"+obj); } }
List轉(zhuǎn)Map:
通常情況下我們從數(shù)據(jù)庫(kù)中獲取的都是多條數(shù)據(jù)的list,即多條指定對(duì)象格式數(shù)據(jù)來(lái)轉(zhuǎn)換Map。
這時(shí)候需要使用一個(gè)Student(int id,int age,String name,String sex)來(lái)輔助我們實(shí)現(xiàn)。
//List轉(zhuǎn)Map /** *通常情況下我們都是充數(shù)據(jù)庫(kù)中查出一個(gè)具體對(duì)象多條數(shù)據(jù)的list,以下我們就使用一個(gè)Student類來(lái)輔助實(shí)現(xiàn) */ public static void list_map(List<Student> studentList){ //第一種方法:使用for循環(huán)遍歷list逐個(gè)插入map中 Map<Integer,Object> map = new HashMap<>(); for(Student student:studentList){ map.put(student.getId(),student); } System.out.println("List轉(zhuǎn)Map的第一種方法:"+map); /** * 第二種方法,使用Java8中stream中的Collectors.toMap方法進(jìn)行轉(zhuǎn)換。 * 如果你的key鍵沒(méi)有設(shè)定唯一值,防止key鍵重復(fù),使用Java8新特性中的lambda表達(dá)式來(lái)表示如果重復(fù),后面就就會(huì)覆蓋 */ Map<Integer,String> map2 = studentList.stream().collect (Collectors.toMap(Student::getId,Student::getName,(key1,key2)->key2)); System.out.println("List轉(zhuǎn)Map的第二種方法:"+map2); }
Map轉(zhuǎn)List:
Map中的value值轉(zhuǎn)List就直接轉(zhuǎn)換即可
//Map轉(zhuǎn)List public static void map_list(Map<Integer,String> map){ List<String> list = new ArrayList(map.values()); System.out.println("Map轉(zhuǎn)List:"+list); }
完整工具類代碼:array_map_list
package com.example.demo.utils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.ArrayUtils; import java.util.*; import java.util.stream.Collectors; /** * @author zhangqianwei * @date 2021/9/6 15:38 */ public class array_map_list { //Array、Map、List相互轉(zhuǎn)換 public static void main(String[] args) { String[] array = {"張三","李四","王五"}; //Array轉(zhuǎn)List array_list(array); array_list2(array); //List轉(zhuǎn)Array List<String> list = new ArrayList<>(); list.add("手機(jī)"); list.add("電腦"); list.add("平板"); list_array(list); //Array轉(zhuǎn)Map array_map(array); String[][] array2 = { { "南京", "江蘇" }, { "武漢", "湖北" }, { "合肥", "安徽" }, { "杭州", "浙江" }, { "長(zhǎng)沙", "湖南" } }; array_map2(array2); //Map轉(zhuǎn)Array Map<Integer,String> map = new HashMap<>(); map.put(1,"一"); map.put(2,"二"); map.put(3,"三"); map_array(map); map_array2(map); //List轉(zhuǎn)Map Student student = new Student(); student.setId(1); student.setName("小張"); student.setAge(18); student.setSex("男"); Student student2 = new Student(); student2.setId(2); student2.setName("小王"); student2.setAge(19); student2.setSex("男"); Student student3 = new Student(); student3.setId(3); student3.setName("小李"); student3.setAge(17); student3.setSex("女"); List<Student> studentList = new ArrayList<>(); studentList.add(student); studentList.add(student2); studentList.add(student3); list_map(studentList); //Map轉(zhuǎn)List map_list(map); } //數(shù)組Array轉(zhuǎn)List /** * 方法一:使用Arrays.asList()方法將數(shù)組轉(zhuǎn)為list,不過(guò)此種方法有限制,返回的對(duì)象是Arrays的內(nèi)部類 * 對(duì)于轉(zhuǎn)換后的list操作仍然反映在原數(shù)組上,因此這個(gè)list是定長(zhǎng)的,無(wú)法使用list的add()喝remove()方法 */ public static void array_list(String[] array){ List<String> list = Arrays.asList(array); System.out.println("數(shù)組轉(zhuǎn)List 的第一種方法:"+list); // list.remove("李四"); // list.add("劉六"); // System.out.println(“修改后:”list); } /** * 方法二:正常情況下array轉(zhuǎn)換為list,使用for循環(huán)將數(shù)組中的元素逐個(gè)添加到一個(gè)空的list中 */ public static void array_list2(String[] array){ List<String> list = new ArrayList<>(); for (int i=0;i<array.length;i++){ list.add(array[i]); } System.out.println("數(shù)組轉(zhuǎn)List 的第二種方法:"+list); list.remove("李四"); list.add("劉六"); System.out.println("修改后:"+list); } //List轉(zhuǎn)Array public static void list_array(List<String> list){ String[] array =list.toArray(new String[list.size()]); System.out.println("List轉(zhuǎn)數(shù)組:"+array); } //Array轉(zhuǎn)Map /** *一維數(shù)組時(shí),奇數(shù)位為key鍵,偶數(shù)位為value,如果有奇數(shù)個(gè)元素,最后一個(gè)舍掉 */ public static void array_map(String[] array) { Map map = MapUtils.putAll(new HashMap(),array); System.out.println("數(shù)組轉(zhuǎn)Map:"+map); } /** * 二維數(shù)組時(shí),當(dāng)成兩個(gè)一維數(shù)組,使用ArrayUtils.toMap()方法轉(zhuǎn)換 */ public static void array_map2(String[][] array2){ Map map2 = ArrayUtils.toMap(array2); map2.put("南昌","江西"); System.out.println("二維數(shù)組轉(zhuǎn)Map:"+map2); } //Map轉(zhuǎn)Array /** * Map只需要value值時(shí),將Map的values轉(zhuǎn)為一維數(shù)組 *使用map.values().toArray()將map轉(zhuǎn)為object數(shù)組,如果想要轉(zhuǎn)為特定類型的數(shù)組需要再進(jìn)一步轉(zhuǎn)換 */ public static void map_array(Map<Integer,String> map){ Object[] obj = map.values().toArray(); /** * 第一種,使用Arrays.copyOf()方法將原數(shù)組內(nèi)的元素拷貝到一個(gè)新的String類型的數(shù)組 * Arrays.copyOf(原數(shù)組,復(fù)制的長(zhǎng)度,指定轉(zhuǎn)換的類型) */ String[] array = Arrays.copyOf(obj,obj.length,String[].class); System.out.println("Map轉(zhuǎn)Array的第一種方法:"+array); /** * 第二種方法,直接強(qiáng)制轉(zhuǎn)換數(shù)組為指定類型 * 此處toArray()中的參數(shù)需要一個(gè)T[] a,new String[0]相當(dāng)于開辟了一個(gè)長(zhǎng)度為0的String[],并且指定了泛型。 * 這里的用new String[0]只是為了指定函數(shù)的形參數(shù),最終返回的String[]的長(zhǎng)度是由你的list存儲(chǔ)內(nèi)容的長(zhǎng)度決定了。 * new String[0]就是起一個(gè)模板的作用,指定了返回?cái)?shù)組的類型,0是為了節(jié)省空間,因?yàn)樗皇菫榱苏f(shuō)明返回的類型。 * 因此list.toArray()方法中的參數(shù)也可以使用String[0]來(lái)指代 */ String[] array2 =map.values().toArray(new String[0]); System.out.println("Map轉(zhuǎn)Array的第二種方法:"+array2); /** * 第三種方法,使用Java8中Arrays.stream()方法,將對(duì)象數(shù)組轉(zhuǎn)為順序Stream,然后使用toArray方法將流的元素累積到新的字符串?dāng)?shù)組中 * String[]::new 是Java8中新定義的一種寫法叫做方法引用,以下這種寫法是調(diào)用了構(gòu)造器引用,為了生成一個(gè)String類型數(shù)組 */ String[] array3 = Arrays.stream(obj).toArray(String[]::new); System.out.println("Map轉(zhuǎn)Array的第三種方法:"+array3); } /** * 第二種:使用for循環(huán)和迭代器遍歷這個(gè)map,將它的key與value逐個(gè)添加到一個(gè)定長(zhǎng)的二維數(shù)組中 */ public static void map_array2(Map<Integer,String> map){ if (map!=null && !map.isEmpty()){ //以map的長(zhǎng)度作為二維數(shù)組的長(zhǎng)度,其中每個(gè)元素就是一個(gè)長(zhǎng)度為2的小數(shù)組存放key與value Object[][] obj = new Object[map.size()][2]; /** * map.entrySet()是把HashMap類型的數(shù)據(jù)轉(zhuǎn)換成集合類型 * map.entrySet().iterator()是去獲得這個(gè)集合的迭代器,保存在iterator里面。 */ Iterator iterator = map.entrySet().iterator(); for(int i=0;i<map.size();i++){ Map.Entry entry = (Map.Entry) iterator.next(); Object key = entry.getKey(); Object value = entry.getValue(); obj[i][0] = key; obj[i][1] = value; } System.out.println("Map轉(zhuǎn)為二維數(shù)組Array:"+obj); } } //List轉(zhuǎn)Map /** *通常情況下我們都是充數(shù)據(jù)庫(kù)中查出一個(gè)具體對(duì)象多條數(shù)據(jù)的list,以下我們就使用一個(gè)Student類來(lái)輔助實(shí)現(xiàn) */ public static void list_map(List<Student> studentList){ //第一種方法:使用for循環(huán)遍歷list逐個(gè)插入map中 Map<Integer,Object> map = new HashMap<>(); for(Student student:studentList){ map.put(student.getId(),student); } System.out.println("List轉(zhuǎn)Map的第一種方法:"+map); /** * 第二種方法,使用Java8中stream中的Collectors.toMap方法進(jìn)行轉(zhuǎn)換。 * 如果你的key鍵沒(méi)有設(shè)定唯一值,防止key鍵重復(fù),使用Java8新特性中的lambda表達(dá)式來(lái)表示如果重復(fù),后面就就會(huì)覆蓋 */ Map<Integer,String> map2 = studentList.stream().collect (Collectors.toMap(Student::getId,Student::getName,(key1,key2)->key2)); System.out.println("List轉(zhuǎn)Map的第二種方法:"+map2); } //Map轉(zhuǎn)List public static void map_list(Map<Integer,String> map){ List<String> list = new ArrayList(map.values()); System.out.println("Map轉(zhuǎn)List:"+list); } }
結(jié)果顯示:
到此這篇關(guān)于Java中Array、List、Map相互轉(zhuǎn)換的方法詳解的文章就介紹到這了,更多相關(guān)Java中集合的轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于java四舍五入方法的基礎(chǔ)學(xué)習(xí)
這篇文章主要給大家介紹了關(guān)于java四舍五入方法的基礎(chǔ)學(xué)習(xí),這是最近做算法題的時(shí)候碰到的這個(gè)問(wèn)題,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07淺析Java8新特性Lambda表達(dá)式和函數(shù)式接口
Lambda表達(dá)式理解為是 一段可以傳遞的代碼。最直觀的是使用Lambda表達(dá)式之后不用再寫大量的匿名內(nèi)部類,簡(jiǎn)化代碼,提高了代碼的可讀性2017-08-08如何用注解的方式實(shí)現(xiàn)Mybatis插入數(shù)據(jù)時(shí)返回自增的主鍵Id
這篇文章主要介紹了如何用注解的方式實(shí)現(xiàn)Mybatis插入數(shù)據(jù)時(shí)返回自增的主鍵Id,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07Java實(shí)現(xiàn)斗地主最簡(jiǎn)代碼實(shí)例
在本篇文章里小編給各位分享的是關(guān)于Java實(shí)現(xiàn)斗地主最簡(jiǎn)代碼實(shí)例,有興趣的朋友們可以參考下。2020-05-05springboot簡(jiǎn)單接入websocket的操作方法
這篇文章主要介紹了springboot簡(jiǎn)單接入websocket的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05Java中notify和notifyAll的區(qū)別及何時(shí)使用
本文主要介紹了Java中notify和notifyAll的區(qū)別及何時(shí)使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09