==================类型转换==================

  在项目中经常会遇到数组转集合、集合转数组、数组之间类型转换等操作

1.数组转集合

为了实现把一个数组转换成一个ArrayList,很多Java程序员会使用如下的代码:

        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)是固定的。如果添加元素是会报错的(但是如果转换后的集合只是用来进行查询不进行增加元素也可以这样转换):

        String str[] = {"1","2","3"};
List<String> strings = Arrays.asList(str);
strings.add("eee");

报错如下:

Exception in thread "main" java.lang.UnsupportedOperationException

at java.util.AbstractList.add(AbstractList.java:148)

at java.util.AbstractList.add(AbstractList.java:108)

at Test.test1(Test.java:31)

at Test.main(Test.java:24)

为了创建出一个真正的ArrayList,代码应该如下所示:(这种方法创建的集合可以进行集合的增加)

        String str[] = {"1","2","3"};
List<String> strings = new ArrayList<String>(Arrays.asList(str));
strings.add("4");
System.out.println(strings);

更加高效的代码如下:

        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操作,参考:https://www.cnblogs.com/qlqwjy/p/9467178.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]

数组转集合、集合转数组、字符串数组与int型、long型数组等的转换的更多相关文章

  1. ipv4的ip字符串转化为int型

    要求: 将现有一个ipv4的ip字符串(仅包含数字,点,空格), 其中数字和点之间的空格(至多一个)是合法的,比如“12 .3. 4 .62”,其他情况均为非法地址.写一个函数将ipv4地址字符串转化 ...

  2. java 将字符串数组变为字典顺序排序后的字符串数组

    import java.util.ArrayList; import java.util.Collections; import java.util.List; public class String ...

  3. c# sql在where查询语句中使用字符串变量与int型变量

    使用where语句访问数据库时where语句用上文中以及定义过的变量来查询. string sql3 = string.Format("update Ships set ContainerN ...

  4. 复杂的字符串数组解析:{"setting":"简单:10:5,一般:5:10,困难:2:20"},使用split多次截取

    "[0,{"id":563,"name":"测试题1","dscr":null,"picId&quo ...

  5. QString和char字符串数组之间的转换 (转)

    做串口通信时,碰到这样的问题,在Qt的界面中,我用QLineEdit对象负责显示发送和接收的文本,对其中的数据进行读取和显示使用的数据类型都是QString:但是,在对串口设备进行读写时,数据使用的形 ...

  6. 057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和

    057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和 本文知识点:求整型数组的数组元素的元素值累加和 案例:求整型数 ...

  7. C++ 字符串分割,并把子字符串转换成int型整数

    主要涉及到string类的两个函数find和substr: find()函数的用法: 原型:size_t find ( const string& str, size_t pos = 0 ) ...

  8. loadrunner 脚本开发-int型变量和字符串的相互转换

    脚本开发-int型变量和字符串的相互转换 by:授客 QQ:1033553122 字符串转化为int型变量 Action2() { int j = 0; j = atoi("12345&qu ...

  9. 字符串集合或字符串数组转换成json数组

    字符串可以是List<String>类型的字符串集合,也可以是String[]类型的字符串数组,二者转换成JSON数组的方式没有什么不同.下面代码注意关键的部分即可(画红线部分). 1. ...

随机推荐

  1. Luogu P3239 [HNOI2015]亚瑟王

    题目链接 \(Click\) \(Here\) 期望神题.最开始一直尝试推朴素一点的,逻辑上的\(DP\)式子,后来发现一直出锅,可能是我的式子没容斥对... 题解中给出的想法是这样的: 首先,如果直 ...

  2. pickle详解

    一.简介 在机器学习中,我们常常需要把训练好的模型存储起来,这样在进行决策时直接将模型读出,而不需要重新训练模型,这样就大大节约了时间 Python提供的pickle模块就很好地解决了这个问题,它可以 ...

  3. Servlet_问题总结

    1.Servlet转发到JSP后页面的CSS样式丢失,页面布局混乱,原来能点的链接现在失效 原因:原来前台页面(JSP|HTML)在引用静态资源(CSS|JS|JSP页面)时使用的是相对路径, 导致由 ...

  4. shipyard 管理swarm集群(附etcd发现服务方法)

    docker swarm集群 第一步:安装swarm集群 192.168.132.131----->(manger1,node) 192.168.132.132----->(manger2 ...

  5. SQL语法基础之DELETE语句

    SQL语法基础之DELETE语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看帮助信息 1>.查看DELETE的帮助信息 mysql> ? DELETE Na ...

  6. OS + linux proxy

    s Linux主机通过代理服务器进行网络连接 http://www.linuxidc.com/Linux/2015-01/111703.htm 新手用Linux做代理服务器 三招搞定 http://b ...

  7. centos 7.4 安装gitlab

    centos 7.4 安装gitlab #curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/scrip ...

  8. 13个.Net开源的网络爬虫

    请点击此处输入图片描述 1:.Net开源的跨平台爬虫框架 DotnetSpider Star:430 DotnetSpider这是国人开源的一个跨平台.高性能.轻量级的爬虫软件,采用 C# 开发.目前 ...

  9. 2018牛客网暑期ACM多校训练营(第二场)G Transform(二分)

    题意 在一个数轴上有n个集装箱,第 i 个集装箱的位置为x[i],且在集装箱内装有a[i]件货物,现在将这些集装箱内的货物进行移动(将一件货物从第 i 个集装箱移动到第 j 个集装箱的花费就为2*ab ...

  10. HDU 1038(速度里程计算 **)

    题意是已知车轮的直径,圈数和时间,求所行驶的里程和速度. 单位换算,代码如下: #include <bits/stdc++.h> using namespace std; const do ...