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),不過這種情況下時(shí)間復(fù)雜度將會(huì)是O(n),空間復(fù)雜度是O(1)。
如果再多加幾個(gè)條件還使用多層for循環(huán)嵌套的話也可以實(shí)現(xiàn),不過時(shí)間復(fù)雜度將會(huì)以指數(shù)級(jí)增長。
我們可以說多層for循環(huán)嵌套可以實(shí)現(xiàn)功能,但就執(zhí)行時(shí)間來說,它絕不會(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ù)雖變量的變化來確定數(shù)量級(jí),數(shù)量級(jí)用O表示,如O(1),O(n),O(n^2)等。
空間復(fù)雜度:
是對(duì)一個(gè)算法在運(yùn)行過程中臨時(shí)占用存儲(chǔ)空間的度量,一個(gè)算法在計(jì)算機(jī)存儲(chǔ)器上所占用的存儲(chǔ)空間包括存儲(chǔ)算法本身所占用的空間,算數(shù)和輸入輸出所占用的存儲(chǔ)空間以及臨時(shí)占用存儲(chǔ)空間三個(gè)部分,算法的輸入輸出數(shù)據(jù)所占用的存儲(chǔ)空間是由待解決的問題來決定的,通過參數(shù)表由調(diào)用函數(shù)而來,它隨本算法的不同而改變,存儲(chǔ)算法本身所占用的存儲(chǔ)空間有算法的書寫長短成正比。算法在運(yùn)行過程中占用的臨時(shí)空間由不同的算法決定。
時(shí)間復(fù)雜度與空間復(fù)雜度沒有必然聯(lián)系,但是也有以空間換時(shí)間或時(shí)間換空間,現(xiàn)今項(xiàng)目中一般要求效率,大部分需要降低執(zhí)行時(shí)間即降低時(shí)間復(fù)雜度,以空間換時(shí)間來提高效率。不過在這兩者之間取舍需要具體問題具體分析。
正文:
Array轉(zhuǎn)List:
有兩種方法可以將array轉(zhuǎn)為list,一種是使用Arrays.asList()方法直接轉(zhuǎn)換,不過此種方法的list長度固定,無法進(jìn)行添加刪除操作。
另一種是使用for循環(huán)遍歷數(shù)組元素逐個(gè)添加進(jìn)一個(gè)空的list中。
/**
* 方法一:使用Arrays.asList()方法將數(shù)組轉(zhuǎn)為list,不過此種方法有限制,返回的對(duì)象是Arrays的內(nèi)部類
* 對(duì)于轉(zhuǎn)換后的list操作仍然反映在原數(shù)組上,因此這個(gè)list是定長的,無法使用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ù)制的長度,指定轉(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è)長度為0的String[],并且指定了泛型。
* 這里的用new String[0]只是為了指定函數(shù)的形參數(shù),最終返回的String[]的長度是由你的list存儲(chǔ)內(nèi)容的長度決定了。
* new String[0]就是起一個(gè)模板的作用,指定了返回?cái)?shù)組的類型,0是為了節(jié)省空間,因?yàn)樗皇菫榱苏f明返回的類型。
* 因此list.toArray()方法中的參數(shù)也可以使用String[0]來指代
*/
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è)定長的二維數(shù)組中
*/
public static void map_array2(Map<Integer,String> map){
if (map!=null && !map.isEmpty()){
//以map的長度作為二維數(shù)組的長度,其中每個(gè)元素就是一個(gè)長度為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ù)庫中獲取的都是多條數(shù)據(jù)的list,即多條指定對(duì)象格式數(shù)據(jù)來轉(zhuǎn)換Map。
這時(shí)候需要使用一個(gè)Student(int id,int age,String name,String sex)來輔助我們實(shí)現(xiàn)。
//List轉(zhuǎn)Map
/**
*通常情況下我們都是充數(shù)據(jù)庫中查出一個(gè)具體對(duì)象多條數(shù)據(jù)的list,以下我們就使用一個(gè)Student類來輔助實(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鍵沒有設(shè)定唯一值,防止key鍵重復(fù),使用Java8新特性中的lambda表達(dá)式來表示如果重復(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 = { { "南京", "江蘇" }, { "武漢", "湖北" },
{ "合肥", "安徽" }, { "杭州", "浙江" }, { "長沙", "湖南" } };
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,不過此種方法有限制,返回的對(duì)象是Arrays的內(nèi)部類
* 對(duì)于轉(zhuǎn)換后的list操作仍然反映在原數(shù)組上,因此這個(gè)list是定長的,無法使用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ù)制的長度,指定轉(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è)長度為0的String[],并且指定了泛型。
* 這里的用new String[0]只是為了指定函數(shù)的形參數(shù),最終返回的String[]的長度是由你的list存儲(chǔ)內(nèi)容的長度決定了。
* new String[0]就是起一個(gè)模板的作用,指定了返回?cái)?shù)組的類型,0是為了節(jié)省空間,因?yàn)樗皇菫榱苏f明返回的類型。
* 因此list.toArray()方法中的參數(shù)也可以使用String[0]來指代
*/
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è)定長的二維數(shù)組中
*/
public static void map_array2(Map<Integer,String> map){
if (map!=null && !map.isEmpty()){
//以map的長度作為二維數(shù)組的長度,其中每個(gè)元素就是一個(gè)長度為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ù)庫中查出一個(gè)具體對(duì)象多條數(shù)據(jù)的list,以下我們就使用一個(gè)Student類來輔助實(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鍵沒有設(shè)定唯一值,防止key鍵重復(fù),使用Java8新特性中的lambda表達(dá)式來表示如果重復(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è)問題,文中通過實(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-07
Java實(shí)現(xiàn)斗地主最簡(jiǎn)代碼實(shí)例
在本篇文章里小編給各位分享的是關(guān)于Java實(shí)現(xiàn)斗地主最簡(jiǎn)代碼實(shí)例,有興趣的朋友們可以參考下。2020-05-05
springboot簡(jiǎn)單接入websocket的操作方法
這篇文章主要介紹了springboot簡(jiǎn)單接入websocket的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05
Java中notify和notifyAll的區(qū)別及何時(shí)使用
本文主要介紹了Java中notify和notifyAll的區(qū)別及何時(shí)使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09

