初步认识equals与==的区别:
==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同
==是指对内存地址进行比较 , equals()是对字符串的内容进行比较
==指引用是否相同, equals()指的是值是否相同
用一张图可以简要的表现他们之间的关系:
==
==与equals()比较
引用
首先明白变量,变量实质就是一块内存单元。这块内存单元存着变量的值。
例如 int a=1;
a是变量的名,1是变量的值。
当变量指向对象时,则称a为引用类型变。
如:a=new A();
a引用了对象A,用过操纵a来操纵对象A。此时,a的值为对象A的地址。
基本类型自动转换:
数值型数据的转换:byte→short→int→long→float→double。
字符型转换为整型:char→int。
数组
在java中,声明一个数组过程中,是如何分配内存的?
1.int[] a;
声明引用类型变量a时,为其分配了引用空间,由于未赋值,此时a为指向任何对象。
2.a=new int[5];
当创建了数组对象,其地址赋值给a,其中刚创建出来的数组元素也相当于引用类型变量。
Java变量一定要初始化吗?
不一定。Java数组变量是引用数据类型变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,即可使用该数组变量。对数组执行初始化,并不是对数组变量进行初始化,而是对数组对象进行初始化——也就是为该数组对象分配一块连续的内存空间,这块连续的内存空间就是数组的长度。
static关键字:
作用:方便在没有创建对象的情况下来进行调用(方法/变量)。
- static方法:
在静态方法中不能访问类的非静态成员变量和非静态成员方法 - statis变量:
静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。 - ststic代码块:
static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
Java中final、finally和finalize的区别:
fianl:被fianl修饰的类,意味着不能再被其他类集成,即不能再作为父类。
finally:finally块内代码都会被执行
基本类型变量都放在栈内存中?
错。应该这样说:所有局部变量都放在栈内存里保存的,不管其是基本类型的变量,还是引用类型变量,都是存储在各自的方法栈区中;但是引用类型变量所引用的对象(包括数组、普通java对象)则总是存储在堆内存中。
集合:
ArrayList:
底层实现是动态数组,线程不安全。
ArrayList的默认初始化容量是10,每次扩容时候增加原先容量的一半,也就是变为原来的1.5倍
在增删时候,需要数组的拷贝复制(navite 方法由C/C++实现)
常用方法:
IsEmpty()
size()
add()
remove()
get()
set()
LinkedList:
底层实现是双向链表[双向链表方便实现往前遍历]
常用方法:
add()
addFirst()
addLast()
getFirst()
getLast()
removeFirst()
removeLast()
set()
size()
Vector:
底层是数组,线程安全现在已少用,被ArrayList替代,原因有两个:
Vector所有方法都是同步,有性能损失。
Vector初始length是10 超过length时 以100%比率增长,相比于ArrayList更多消耗内存。
参考资料:https://www.zhihu.com/question/31948523/answer/113357347
总的来说:查询多用ArrayList,增删多用LinkedList。
ArrayList增删慢不是绝对的(在数量大的情况下,已测试):
如果增加元素一直是使用add()(增加到末尾)的话,那是ArrayList要快
一直删除末尾的元素也是ArrayList要快【不用复制移动位置】
至于如果删除的是中间的位置的话,还是ArrayList要快!
HashSet:
底层是哈希表(一个元素为链表的数组)+红黑树
HashSet操作底层是通过调用HashMap实现的,HashSet的add()方法添加的元素存储在HashMap的key,然后为value赋值一个静态空对象。
HashSet不能存储重复元素,因为HashMap的key集合不可以重复,本质也是通过equals()和hashCode()来判定两个对象是否重复,因此将对象存储在HashSet之前,必须先重写对象的equals()和hashCode()方法。
如果不同的key产生相同的散列码,则会生成链表。