Java的数据类型

目录

数字

字符型和字符串型

字符型

字符串

时间

Arrays

 


数字

内置类型可以直接使用定义变量,包装期类型相当于对象类型;c语言或perl语言没有制定数值类型的大小和精度,跟平台有关系,与他们不同,java为了实现可移植性,明确定义了数值类型的大小和精度,

其实boolean也算上(boolean变量编译后被转换为int变量,占用4个字节的存储空间,true被转换为1赋值给int变量,false被转换为0赋值给int变量。因此,程序需要判断数值的真或假时,即可以用boolean类型变量,也可以用int类型的变量,当然也可以用byte类型的变量)

类型列表:

内置类型对象包装器大小-字节内置大小-位解释
byteByte18有符号整形
shortShort216有符号整形
intInteger432有符号整形
longLong864有符号整形
floatFloat432浮点数
doubleDouble864浮点数
charCharacter216无符号Unicode字符
n/aBigIntegerunlimitedunlimited任意大小的不可变整数值
n/aBigDecimalunlimitedunlimited任意大小和精度的不可变浮点数值

需要注意的是,上面的char,专门用于表示和操作unicode字符的数据类型。

包装器的作用就是将一个数字构成的字符串转换为数值类型

基本类型的数字一个常遇到的问题是,有时候需要将基本类型的数字传递给一个方法,但是方法需要一个Object参数,此时可以使用自动装箱和自动拆箱实现

java.lang.Math类将整个”数学库“集成在一个类中,包括求平方根,最小最大值,取整,三角函数,随机数发生器等,比如随机数

 

字符型和字符串型

字符型

字符型通常用于表示单个字符,字符型值必须使用单引号(‘)括起来。Java语言使用16位的Unicode字符集作为编码方式,而Unicode被设计成支持世界上所有书面语言的字符,因此Java程序支持各种语言的字符

字符型值有三种表示形式:

  • 直接通过单个字符来指定字符型值,如’A‘,’2‘等
  • 通过转义字符表示特殊字符型值,如’\n‘,'\t'等
  • 直接用Unicode值表示字符型值,格式’\uXXXX‘,其中XXXX代表一个十六进制的整数

常用的转义字符:

转义字符unicode表示解释
\b\u0008退格符
\n\u000a换行符
\r\u000d回车符
\t\u0009制表符
\"\u0022双引号
\'\u0027单引号
\\\u005c反斜线

字符型值也可以使用十六进制编码方式来表示,范围是’\u0000‘~'\uFFFF' ,一共可以表示65536个字符,其中前256个’\u0000‘~'\u00FF'字符和ASCII吗中的字符重合;计算机在底层保存字符时,实际是保存该字符对应的编号,所以char类型的值也可以直接作为整形值使用,相当于一个十六位的无符号整数,范围为0~65536,当然也可以进行加减乘除等数学运算,比较大小;如果吧一个0~65536范围内的整形值赋给char类型变量,系统会自动吧这个int整形当成char类型来处理

范例:

public class test {
public static void main(String[] args){
	// 定义一个单个字符的字符变量
	char achar='中';
	System.out.println(achar);
	//定义一个转义字符值
	char enterchar='\r';
	System.out.println(enterchar);
	//使用Unicode编码值来定义字符值
	char bchar='\u9999';
	System.out.println(bchar);
	//使用achar中文字符值来定义整形值
	int c_i=achar;
	System.out.println(c_i);
	//使用整形值来定义字符值
	char char1=97;
	System.out.println(char1);
}
}

Java没有提供字符串的基本数据类型,但是提供了String类来表示字符串,下面将介绍。

Java语言中的单引号,双引号,反斜线都有特殊用途,如果一个字符串中包含了这些特殊字符,则应该使用转义字符的表示形式,比如使用一个绝对路径“c:\javacode”中表示是不对的,因为Java会把反斜线当成转义字符,所以应该写为"c:\\javacode"

字符串

字符串一连串的字符序列,Java没有提供字符串的基本数据类型,Java的字符串用String来表示,他是一个预定义的类型(类),也就是一个对象,当然有他自己的方法。

给定一个字符串对象构造了实例后不能改变,比如String str1=“Hello” + “gel”,变量str1所引用的特定内容就不可以改变,直到这个对象被销毁;当然你可以让变量引用另一个字符串,甚至可以引用一个从原来字串中派生出来的子串,例如str1=str1.trim().即便是toUpperCase()这样的方法也不能改变字符串对象,只能返回一个新的字符串对象,包含转换后的字符串。

String是Java的 一个基本(类)型,与核心API中大多数其他类不同,字符串行为不可变,因为他有final标记,不能从他派生 出子类,字符串不变性是Java虚拟机的基本原理之一,特别是涉及到多线程编程或者来自多个组织的软件协同工作。可以安全地将不可变对象传递给第三方库并且期望不可修改。

还有另两个类StringBuffer和StringBuilder,他们都是用来代表字符串对象,可以修改

当一个StringBuffer被创建以后,总过StringBuffer提供的append(),insert(),reverse(),setCharAt(),setLength()等方法可以改变这个字符串对象的字符序列,一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。

JDK1.5增加了一个StringBuilder类,也代表字符串对象,其实他和StringBuffer基本类似,两个类的构造器和方法也基本相同,区别是,StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高,所以有限使用StringBuilder类。

当然c语言的字符串是一个字符数组,比如char*

String 简单用法,既然是对象,就有一些方法可以使用,

使用String substring(int beginIndex)或者String substring(int beginIndex,int endIndex)的方法返回一个新的字串

        //String a="Hello world!";
        String a=new String("Hello world!");
        System.out.println(a);
        String b=a.substring(1);
        System.out.println(b);

string的char charAt(int index) 获取字符串中制定位置的字符,其中index为下标,从0到length-1;以下是打印字符串中的字符

看另一个例子:

上面程序,有三个字符串直接量,还会生成额外的2个字符串直接量,“Hello ”和“Zhangsan”生成的“Hello Zhangsan”,和“Hello Zhangsan”连接“Lisi”生成的“Hello ZhangsanLisi”

从上面可以看到,由于String是不可变的,将生成很多额外历史变量。使用StringBuffer和StringBuilder可以避免此问题

上面以此为创建一个StringBuilder对象,追加插入字符串,替换删除操作,反转,最后打印

另外String有一个很有用的功能是将字符串分割为数组:

public class StringSplitdemo {
    public static void main(String[] args) {
        String str = "code1,code2,,code4";
        String [] result_split = str.split(",");
        System.out.println(result_split.length);
        for(String item_str : result_split){
            System.out.println(item_str);
        }
        System.out.println("------------------------------");
        String [] result_split2 = str.split("[,]+");
        System.out.println(result_split2.length);
        for(String item_str : result_split2){
            System.out.println(item_str);
        }
    }
}

总结:

Java中String,StringBuilder和StringBuffer的区别
1、运算速度比较(通常情况下):StringBuilder > StringBuffer > String
String是final类不能被继承且为字符串常量,而StringBuilder和StringBuffer均为字符串变量。String对象一旦创建便不可更改,而后两者是可更改的,它们只能通过构造函数来建立对象,且对象被建立以后将在内存中分配内存空间,并初始保存一个null,通过append方法向StringBuffer和StringBuilder中赋值
2. 线程安全性
StringBuilder(非线程安全)
而StringBuilder的方法没有该关键字修饰,所以不能保证线程安全性。是JDK1.5新增的,该类提供一个与StringBuffer兼容的 API,但不能保证同步,所以在性能上较高。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
StringBuffer(线程安全的)
StringBuffer中大部分方法由synchronized关键字修饰,在必要时可对方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致,所以是线程安全的。类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符
3. 总结
String:适用于少量的字符串操作。
StringBuilder:适用于单线程下在字符串缓冲区进行大量操作。
StringBuffer:适用于多线程下在字符串缓冲区进行大量操作。

时间

Java 8之前,存在Data和Calendar用来处理日期,时间的类,包括创建日期,时间对象,获取系统当前日期,时间等;但是,Data无法实现国际化,并且他对不同属性也使用不统一的偏移量,比如月份小时都是从0开始,但是天从1开始,年是1900年开始。Calendar实现太复杂。自从Java 8引入新的日期时间包,提供了很多有用的功能,比如对日期时间的加减操作,所有对象几乎不可变-线程安全等。

新的API定义了十几个大类,可表示“连续的”和“人性化”的时间,这里的时间基于UNIX时间,表示为一个单调递增的数;UNIX的时间值0表示1970年 1月1日0时0分0秒(UTC),UNIX系统诞生的那一刻,增量的一个单位代表1秒钟,并且这种时间表示格式已被用作大多数操作系统的时间基准。

新的Data/Time API包含在5个包中,其中顶层包含了最常用的API

名称描述
java.time表示日期,时间,瞬时和期间的公共类
java.time.chrono非ISO日历系统的API
java.time.format格式化类
java.time.temporal使用fields,adjusters,units访问日期和时间
java.time.zone支持时区及规则

第一个基本包java.time,包含了十几个类,几个枚举雷和一个通用的异常类,基础类:

描述
Instant自1970-01-01以来的一个时间点,以纳秒(nanosecond)为单位
Duration时长,以纳秒(nanosecond)为单位

“人性化”类:

描述
DateTimeFields存储域-值对的一个映射
DayOfWeek星期中的一天(如Tuesday)
LocalDate本地日期(年月日)
LocalTime本地时间(时分秒)
LocalDateTimeLocalDate和LocalTime组合
MonthDay月日
OffsetTime带时区偏移的时间,类似-04:00,不包括日期或时区值
OffsetDateTime带时区偏移的日期时间,类似-01:00
Period时间长度的描述,如2月3天
ZonedDateTime带时区和偏移的日期时间
Year
YearMonth年月

下面是格式化日期时间的格式字符:

符号含义显示形式例子
G公元文本AD
y公元年年份2018;18
D一年中的几天数字100
M/L数字/文本7;07;Jul;July;J
d一年中的第几天数字20
Q/q一年中的第几季度数字/文本3;03;Q3;3rd quarter
Y年份1999;99
w一年中的某周数字10
W一个月中的某一周数字4
e/c星期中的本地天数数字/文本2:02;Tue;Tuesday;T
E星期中的第几天文本Tue;Tuesday;T
F某月中星期几出现的序数数字3
aAM/PM表示文本PM
h12小时制的小时(1-12)数字12
H24小时制的小时(0-23)数字20
k12小时制的小时(0-11)数字2
K24小时制的小时(1-24)数字24
m小时内的几分数字30
s分内的几秒数字50
S毫秒数字987
A千分之一(纳)天数字1234
n纳秒数字987654321
N十亿分之一(纳)天数字1234000000
V时区ID值文本Z;-08:30
z时区名文本PST
X时区偏移ZOffset-XZ;-08;-0830
x时区偏移Offset-x +0000;-08
Z时区的GMT偏移Offset-Z +0000;-0800
O本地时区偏移Offset-OGMT+8;GMT+08:00
p填充下一个填充符1

 以下是一些例子:

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Calendar;
public class test {
	public static void main(String []args) {
		
		System.out.println("---日期,日历的输出,格式化---");
        LocalDate ld = LocalDate.now();
        System.out.println(ld);
        LocalTime lt = LocalTime.now();
        System.out.println(lt);
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);
        
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        // 使用格式化对象将一个日期格式化为ISO8681标准,使用斜线代替破折号
        System.out.println(df.format(LocalDate.now()));
        // 使用 同一个格式化对象将字符串格式化为日期
        System.out.println(LocalDate.parse("2019/01/01",df));
        
        // 两个日期的加减
        System.out.println("---两个日期的加减---");
        LocalDate d1 = LocalDate.of(2000, 01, 01);
        LocalDate lnow = LocalDate.now();
        Period diff = Period.between(d1, lnow);
        System.out.println(diff);
        System.out.printf("The 21st century (up to %s) is %s old%n",lnow,diff);
        System.out.printf("The 21st century is %d years,%d months and % days old%n",
        		diff.getYears(),diff.getMonths(),diff.getDays());
        
        // 日期,日历的加减
        System.out.println("---日期,日历的加减---");
        LocalDate now = LocalDate.now();
        Period p=Period.ofDays(365);
        LocalDate then=now.plus(p);
        System.out.printf("365 days from %s is %s %n",now,then);
        
        // 与传统日期的接口
        System.out.println("---与传统日期的接口---");
        Date legacyd = new Date();
        System.out.println(legacyd);
        LocalDateTime ndate = LocalDateTime.ofInstant(legacyd.toInstant(), ZoneId.systemDefault());
        System.out.println(ndate);
        Calendar c = Calendar.getInstance();
        System.out.println(c);
        LocalDateTime nc = LocalDateTime.ofInstant(c.toInstant(), ZoneId.systemDefault());
        System.out.println(nc);
    }
}

结果

---日期,日历的输出,格式化---
2019-04-14
19:27:50.878
2019-04-14T19:27:50.878
2019/04/14
2019-01-01
---两个日期的加减---
P19Y3M13D
The 21st century (up to 2019-04-14) is P19Y3M13D old
The 21st century is 19 years,3 months and  13ays old
---日期,日历的加减---
365 days from 2019-04-14 is 2020-04-13 
---与传统日期的接口---
Sun Apr 14 19:27:50 CST 2019
2019-04-14T19:27:50.987
java.util.GregorianCalendar[time=1555241271002,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=3,WEEK_OF_YEAR=16,WEEK_OF_MONTH=3,DAY_OF_MONTH=14,DAY_OF_YEAR=104,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=27,SECOND=51,MILLISECOND=2,ZONE_OFFSET=28800000,DST_OFFSET=0]
2019-04-14T19:27:51.002

从上面的例子可以看到使用了一些公共的方法,因为没有set方法,get方法通常无意义,新增的一些方法:

名称描述
at与另一个对象组合
format给定格式化器产生一个格式化字符串)
from工厂方法,将输入参数转化为目标实例
get从实例中获取一个域
is检查给定对象的状态
minus减去一个数后返回结果副本
of工厂方法,解析输入,创建新方法
parse工厂方法,解析单个输入字符串,产生目标实例
plus加上一个数后返回结果副本
to将该对象转换为另一个类型
with修改制定域并返回一个副本。替换了set方法

 日期一些函数:

/**
     * 返回指定日期所在年份的第几周
     * @param dateStr
     * @return
     */
    public static int weekOfYear(String dateStr){
        // 格式化字符串
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = format.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Calendar calendar = Calendar.getInstance();
        // 国内第一天设置
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(date);

        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取当前时间所在周的第一天
     * @param date
     * @return
     */
    public static Date getBeginDayOfWeek(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 因为按照Calendar类获取的周日为一周的第一天,按照中国习惯,所以这里需要特殊处理
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return cal.getTime();
    }

    /**
     * 根据日期获得所在月天数
     *
     * @param date
     * @return
     */
    public static Integer getDaysOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

Arrays

Arrays类位于 java.util 包中,主要包含了操纵数组的各种方法;使用时导包:import java.util.Arrays
其中常用的:

1,void Array.sort(Object[] array)
功能:对数组按照升序排序
2,Arrays.sort(Object[] array, int from, int to)
功能:对数组元素指定范围进行排序
3,public static String toString(Object[] array)
功能:返回数组的字符串形式
4,public static <T> List<T> asList(T... a)
将一个数组转为list

 举例

public class Demo {
    public static void main(String[] args) {
        String [] arr_str = {"code4","code2","code3"};
        List<String> list1 = Arrays.asList(arr_str);

        for(String item : list1){
            System.out.println(item);
        }
        System.out.println("------------------------------");
        Arrays.sort(arr_str);
        for(String item_str : arr_str){
            System.out.println(item_str);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朝闻道-夕死可矣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值