基本数据类型
八种数据类型:byte、int、short、long、float、double、char、boolean
聊一些基本数据类型中有意思的事情
知识点1、基本数据类型是互通的
基本数据类型本质上都是字节,是01组成的数据
为什么基本数据类型是互通的,因为在不考虑精度的情况下,除了boolean类型,基本数据类型是可以直接强转输出的
怎么证明这一点呢?
// 精度相同的场景下:
System.out.println((byte) 98);
System.out.println((byte) 'b');
在精度相同的场景下,将int类型的98和char类型的'b'转为byte类型输出,得到的结果都是98
一方面是PrintStream输出流方法的逻辑,另一方面说明了将98转为二进制数据,这个数据可以代表int 98
,也可以代表char 'b'
,当然它也可以代表那一串byte数据
// 不同精度的场景下:
System.out.println((byte) 2.1f);
System.out.println((byte) 2.1d);
而在不同精度的场景下,虽然也能把float、double转为byte,但是会损失精度
其实本质上是先把float和double转成了int,再进一步转成byte
当然,剩下的boolean是无法和int互转的,因此就无法和byte、char互转
那么基本数据类型的互转有什么用呢?
利用字节流读取文件的时候,读取到的都是byte数据,可以直接利用基本数据类型的互通性进行数据转换
FileInputStream fis = new FileInputStream("C:\\Users\\g30038553\\Desktop\\temp\\tag加密\\tag65536特殊字符.txt");
byte[] bytes = fis.readAllBytes();
// 直接读全文,如果是读中文,增加标准字符集转码
String origin = new String(bytes, StandardCharsets.UTF_8);
System.out.println(origin);
// 如果想遍历做处理,也可以转char处理
for (byte : bytes) {
char c = (char) byte
// dosomething
}
// 也可以利用String#charAt方法遍历
for (int i = 0; i < origin.length(); i++) {
String word = String.valueOf(origin.charAt(i));
// dosomething
}
知识点2、求余与除法
在java的除法中, 表达式 a/b 的商会向 0 取整
a % b 的余数的定义是 (a/b)*b + a % b == a
等式变换一下就是a % b == a - (a / b) * b
由于a / b向0取整这个是确定的,因此很容易算出a % b 的结果
这也是为什么14/-3 的商都是 -4,但 -14 % 3 是 -2,而 14 % -3 是 2
迭代器和集合
知识点1、区别
可迭代对象接口Iterable是集合的父接口
其中默认实现了forEach方法,有了这个方法,类似列表这种可迭代对象就可以使用forEach完成遍历
除此之外,可迭代对象中的Iterator<T> iterator();
要求实现类必须能返回一个迭代器对象
public interface Iterator<E> {
boolean hasNext();
E next();
……
}
其中最核心的是hasNext和next方法
例如ArrayBlockingQueue中的内部类就是一个迭代器
private class Itr implements Iterator<E> {
private int cursor;
private E nextItem;
private int nextIndex;
private E lastItem;
private int lastRet;
private int prevTakeIndex;
private int prevCycles;
……
其中保存了当前的游标、指向下一个数据或最后一个数据的指针
思考一下,既然Iterable接口中已经有了默认的forEach方法实现,为什么还要有Iterator<T> iterator();
要求实现类必须能返回一个迭代器对象?
首先
iterator()
方法是java5就存在的方法,而forEach方法是java8才出现的方法,为了向前兼容,必须保留iterator()
方法其次,forEach的实现是for循环语法糖,而编译的时候,for循环实际会被编译为
for (I #i = Expression.iterator(); #i.hasNext(); )
即forEach的底层实现也是依赖于Iterator的
知识点2、集合的实现形式
两种:数组、链表
最简单的ArrayList就是基于数组实现的,由于数组必须有一个初始值,搞小了不够用,搞大了又会占太多内存,因此往往基于数组的集合都会添加一个扩缩容的能力
resize()
,每次添加元素队满时,进行以2倍为基准的扩容,或减少元素发现队空时,以1/2为基准缩容例如LinkList,链表形式比较简单,只需要一个后继指针就可以实现一个链式的模型,创建LinkList时,持有的往往是链表中的头节点
评论区