目录
- java异常处理
-
-
- Exception类的层次
- Java内置异常类
- 异常方法
-
- JAVA基础
-
- JAVA反射
-
- 什么是反射?
- 为什么需要反射?
- JAVA接口
-
- 为什么要用接口?
- JAVA构造方法
- JAVA集合
-
- 线程安全的集合类是什么?
- list :LinkedList,ArrayList 和vector
- set:HashSet和TreeSet
- map:HashMap、TreeMap和HashTable
-
- 线程安全
- 空值
- 继承和接口
- 顺序
- 构造函数
- 数据结构
- list、set和map的区别
- Set集合的底层如何保证数据不重复?
- ArrayList与LinkedList的区别
- java面向对象
- Java基础数据有哪些类型?(5分)
- int 和 Integer 有什么区别?(5分)
- ArrayList和LinkedList有什么区别
- JAVA中的集合类
-
- 第一代线程安全集合
- 第二代非安全集合线程
- 第三代线程安全集合
- jdk1.8的新特点是什么?
-
-
- 默认接口法
-
- JAVA抽象和接口有什么区别?
- Java中==和equals有哪些区别
- Java中重写和重载有什么区别?
- String ,StringBuffer,StringBuilder区分和使用场景
- Redis
-
- Redis什么是线程模型,为什么单线程快?
- JAVA中数据结构
-
- Java哈希表
-
- hashCode() 和equals()上述方法的重要性?
- 请说一说,Java中的HashMap工作原理是什么?
- 什么是介绍hashmap?
- HashMap和LinkedHashMap的区别?
- HashMap和HashTable有什么区别?
- final关键字在Java它的作用是什么?
- static的作用
-
- super的作用
- String底层存储是什么?
- sleep()与wait()区别?
- MySQL索引有哪些类型?
- MySQL事务的四大特点
- 如何避免并发?
- MySQL中count(id)、count(1)、count(字段)的区别?
- 您对数据库优化了解多少?
- 抽象和普通有什么区别?(5分)
- java反射获取三种方式
- HashSet 判断两个元素相等性的方法
- Java多线程
-
- 为什么要用?java线程池
- Redis
-
- Redis能做什么?
- Redis与传统的关系数据库有什么区别?
- Redis数据类型是什么?
- Redis为什么单线程这么快?
- set和zset有什么区别?
- 1.7 说一下Redis中的watch命令
- 1.8 说说Redis中List相关操作结构
- 1.9 如何设计?Redis过期时间?
- MySQL部分
-
- 存储引擎的区别
- 谈谈你对数据库优化的理解
- 该如何优化Mysql的查询
- 了解数据库的锁吗?
- 如何高效地插入数据?
- 死锁发生在什么情况下?
- 谈谈数据库死锁的解决方案
- 介绍数据库分页
- 介绍一下SQL中聚合函数
- 表跟表是如何相关的?
- 说说你对外部连接的理解
- 谈谈数据库的左右连接
- Where和HAVING有什么区别
- 索引
-
- 说一说你对Mysql索引的理解
- mysql有哪些索引
- MySQL如何判断是否需要索引?
- 那些情况不适合创建索引
- 索引的实现原理
- 聚簇索引有哪些类别?
- 聚簇索引和非聚簇索引有什么区别?
- mysql存储引擎有哪些?
- Mysql隔离等级有哪些?
- 单例模式
- 手写单例模式
-
- 手写线程安全单例模式
- 高并发
-
- 高并发有哪些实践方案?
- 高性能时间方案
- 3.2.2 实践方案高度可用
- 3.2.3 实践计划的高扩展
- get请求与post请求有什么区别?
- Linux简单命令
-
- 查看空间,内存
- 查询日志
- 查端口号
- mikdir——Make Directory
- pwd — Print Working Directory
- cd — Change Directory
- .rmdir— Remove Directory
- rm— Remove
- cp— Copy
- mv— Move
- grep
- find
- tar
- gzip
- 什么是JVM
-
- 程序计数器
- 虚拟机栈
- 内存溢出
- 线程操作诊断
-
- 本地方法栈
- 堆
- 内存溢出
- 常量池
-
- 通过反编译来查看类的信息
- 常量池与串池的关系
-
- 串池StringTable
-
- 特征
- intern方法 1.8
-
- intern方法 1.6
- StringTable调优
- 6、直接内存
-
- 文件读写流程
- 使用了DirectBuffer
- 释放原理
- allocateDirect的实现
- DirectByteBuffer类
- 直接内存的回收机制总结
- 三 垃圾回收
-
-
- 1.如何判断对象可以回收
-
- 引用计数法
- 可达性分析算法
- 物种引用
- 2、垃圾回收算法
- 4、垃圾回收器
-
- 什么是JVM内存结构
- 什么是JVM内存模型
- 堆和栈有什么区别
- 说一说对 OOM 的认识?以及如何排查 OOM 的问题?
- 谈一谈 JVM 中的常量池?
- java容器(集合)
-
- java容器都有哪些
- Collection 和Collections有什么区别
- List、Set、Map 之间的区别是什么?
- 如何决定使用 HashMap 还是 TreeMap?
- 说一下 HashMap 的实现原理?
- 说一下 HashSet 的实现原理?
- ArrayList 和 LinkedList 的区别是什么?
- 如何实现数组和 List 之间的转换?
- ArrayList 和 Vector 的区别是什么?
- Array 和 ArrayList 有何区别?
- 在 Queue 中 poll()和 remove()有什么区别?
- 哪些集合类是线程安全的?
- 迭代器 Iterator 是什么?
- 怎么确保一个集合不能被修改?
- JavaBean
- 方法的重写
- IO流
- Collection
-
- Arraylist
- LinkedList
- Vector & Stack
- 1.8 以前一直采用头插法的是由于计算机的局部性原理,主要是时间局部性原理,即一个最近被访问过的对象,很有可能很快会被再访问到,基于该假设,在头节点插入,可以有效的提高查询的效率,在发生并发问题时,完全可以使用 concurrent map来解决
- HashMap的线程不安全带来了循环链表问题 可以使用Collections中的SynchronizedMap,concurrentHashMap,HashTable解决,推荐使用ConcurrentHashMap
- HashMap 每次 * 2 的原因:1)2 的幂次可以用 & 的方式进行取余运算,效率更高;2)在扩容移动链表节点时,节点在新数组中的位置只可能是原位置 i 或 i + oldCap 旧数组长度,扩容时效率更高
-
- 什么是反射
- 为什么需要反射
- 反射需要用到的API
- 常用方法
- 反射的应用距离
-
- 物料类
- 练习:获取类对象
- 练习:获取成员变量
-
- 练习:通过字节码对象获取类的成员方法
- 4.5 练习 : 通过字节码对象获取类的构造方法
- 练习 : 创建对象
- 5.1 创建 : 测试物料类
- 练习 : 创建测试类
- 分组查询
-
- 分组过滤查询
- 限定查询
- 查询前5行记录
-
- 经典应用
- 查询总结
-
- sql语句编写顺序
- sql语句执行顺序
- 子查询(作为条件判断)
-
- 查询工资大于bruce 的员工信息
- 子查询(做为枚举查询条件)
-
- 查询与名为'King'同一部门的员工信息
- 工资高于60部门所有人的人的信息
java异常处理
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error;如果你用System.out.println(11/0),那么由于你将0用做了除数,会抛出java.lang.ArithmeticException的异常。
异常发生的原因有很多,通常包含了以下几大类: 1.用户输入了非法数据。 2.要打开的文件不存在。 3.网络通信时连接中断,或者JVM内存溢出。 这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其他一些是因为物理错误引起的。 要理解Java异常处理时如何工作的,你需要掌握以下三种类型的异常: 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。 运行时异常:运行时异常是可以被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。 错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译时也是检查不到的。
Exception类的层次
所有的异常类是从java.lang.Exception类继承的子类。 Exception类是Throwable类的子类。除了Exception类外,Throwable还有一个子类Error。 java程序通常不捕获错误。错误一般发生在严重故障时,它们在java程序处理的范畴之外。 Error用来指示运行时环境发生的错误。 例如,JVM内存溢出,一般地,程序不会从错误中恢复。 异常类有两个主要的子类:IOException类和RuntimeException类。
Java内置异常类
java语言定义了一些异常类在java.lang标准包中。 标准运行时异常类的子类是最常见的异常类。由于java.lang包是默认加载到所有的java程序的,所以大部分从运行时异常类继承而来的异常都可以直接使用。 java根据各个类库也定义了一些其他的异常,下面的表中列出了java的非检查性异常。
异常方法
捕获异常
使用try 和catch关键字可以捕获异常。try/catch代码块放在异常可能发生的地方。 try/catch代码块中的代码称为保护代码。
try { //程序代码 }catch(ExceptionName e1) { //Catch块 }
Catch语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try后面的catch块就会被检查。如果发生的异常包含在catch块中,异常会被传递到该catch,这和传递一个参数到方法是一样的。
实例
ExcepTest.java
import java.io.*;
public class ExcepTest{
public static void main(String args[]){
try{
int a[] = new int[2];
System.out.println("Access element three :" + a[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Exception thrown :" + e);
}
System.out.println("Out of the block");
}
}
以上代码编译运行输出结果如下:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 Out of the block
https://blog.csdn.net/weixin_45927841/article/details/123217462?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-123217462-blog-124825404.pc_relevant_antiscanv3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-123217462-blog-124825404.pc_relevant_antiscanv3&utm_relevant_index=2
作者:晗江雪 链接:https://www.nowcoder.com/discuss/836019 来源:牛客网
JAVA基础
JAVA反射
什么是反射?
反射是JAVA的特征之一,它允许运行中的JAVA程序对自身的检查 反射非常强大,它甚至能直接操作程序的私有属性。我们前面学习都有一个概念,被,被private封装的资源只能类内部访问,外部是不行的,但这个规定被反射赤裸裸的打破了。 反射就像一面镜子,它可以在运行时获取一个类的所有信息,可以获取到任何定义的信息(包括成员变量,成员方法,构造器等),并且可以操纵类的字段、方法、构造器等部分。
为什么需要反射?
如果向创建对象,我们可以直接new User();为何要通过反射去创建对象呢?
那我要先问你个问题了,你为什么要去餐馆吃饭呢? 例如:我们要吃个牛排大餐,如果我们自己创建,就什么都得管理。 好处是,每一步做什么我都很清晰,坏处是什么都得自己实现,那不是累死了。牛接生你管,吃什么你管,屠宰你管,运输你管,冷藏你管,烹饪你管,上桌你管。就拿做菜来说,你能有特级厨师做的好? 那怎么办呢?有句话说的好,专业的事情交给专业的人做,饲养交给农场主,屠宰交给刽子手,烹饪交给特级厨师。那我们干嘛呢? 我们翘起二郎腿直接拿过来吃就好了。 再者,饭店把东西做好,不能扔到地上,我们去捡着吃吧,那不是都成原始人了。那怎么办呢?很简单,把做好的东西放在一个容器中吧,如把牛排放在盘子里。
我们在后面的学习中,会学习框架,有一个框架Spring就是一个非常专业且功能强大的产品,它可以帮我们创建对象,管理对象。以后我无需手动new对象,直接从Spring提供的容器中的Beans获取即可。Beans底层其实就是一个Map<String,Object>,最终通过getBean(“user”)来获取。而这其中最核心的实现就是利用反射技术。
总结一句,类不是你创建的,是你同事或者直接是第三方公司,此时你要或得这个类的底层功能调用,就需要反射技术实现。有点抽象,别着急,我们做个案例,你就立马清晰。
package cn.tedu.reflection;
import java.lang.reflect.Constructor;
import org.junit.Test;
/**本类用来测试反射*/
public class TestReflect {
//7.通过单元测试方法,创建Student目标类的对象
@Test
public void getObject() throws Exception {
//1.获取字节码对象
Class<?> clazz = Student.class;
//2.通过反射技术创建目标类的对象,注意抛出异常
/*反射创建对象方案1:通过触发目标类的无参构造创建对象*/
Object o = clazz.newInstance();
System.out.println(o);//这一步已经获取到了对象Student{name='null', age=0}
/*反射创建对象方案2:通过触发目标类的全参构造创建对象 * 思路: * 1.先获取指定的构造函数对象,注意需要指定构造函数的参数,传入的是.class字节码对象 * 2.通过刚刚获取到的构造函数对象创建Student目标类的对象,并且给对象的属性赋值 * */
//3.获取目标类中指定的全参构造
Constructor<?> c = clazz.getConstructor(String.class, int.class);
//System.out.println(c);
//4.通过获取到的构造函数:创建对象+给对象的属性赋值
Object o2 = c.newInstance("赵六", 6);
System.out.println(o2);
}
}
JAVA接口
为什么要用接口
接口被用来描述一种抽象。因为JAVA不像C++一样支持多继承,所以JAVA可以通过实现接口来弥补这个局限 接口也可以用来实现解耦。 接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非final的变量,接口的静态成员变量要用static final public 来修饰 \接口中的方法都是抽象的,是没有方法体的,可以使用接口类型的引用指向一个实现了该接口的对象,并且可以调用这个接口中的方法。
可以直接把接口理解为100%的抽象类,既接口中的方法必须全部是抽象方法。(JDK1.8之前可以这样理解)
和抽象类区别:
● 抽象类实例化是变量指向实现抽象方法的子类对象,接口变量必须实现所有接口方法的类对象 ● 抽象类要被子类继承,接口被类实现 ● 接口只能做方法申明,抽象类可以做方法实现 ● 接口定义的变量只能是公共的静态的常量,抽象类中是普通变量 ● 接口可以通过匿名内部类实例化
● 一个抽象类可以是public、private、protected、default,接口只有public; ● 一个抽象类中的方法可以是public、private、protected、default,接口中的方法只能是public和default ● abstract不能与final并列修饰同一个类;abstract 不能与private、static、final或native并列修饰同一个方法 ● 抽象方法不能有方法体,抽象方法不能使用private修饰符,也不宜使用默认修饰符(default)接口 不可以实例化 。 通过接口实现类创建对象
JAVA构造方法
构造方法的声明:
修饰符 class_name(类名) (参数列表){
逻辑代码
}
- 构造⽅法的⽅法名和类名⼀致(包括⼤⼩写)
- 构造⽅法没有返回值类型(连void都没有)
- 构造⽅法可以重载
- 构造⽅法不可以⼿动调⽤,只能在创建对象的时,jvm⾃动调⽤
- 构造⽅法在创建对象时只能调⽤⼀次
- 构造⽅法的⽅法名和类名⼀致(包括⼤⼩写)
- 构造⽅法没有返回值类型(连void都没有)
- 构造⽅法可以重载
- 构造⽅法不可以⼿动调⽤,只能在创建对象的时,jvm⾃动调⽤
- 构造⽅法在创建对象时只能调⽤⼀次
当⼀个类中,没有定义构造⽅法 系统会⾃动提供⼀个公开的 ⽆参的构造⽅法 当类中已经定义了构 造⽅法,系统不再提供⽆参公开构造,如果需要使⽤⽆参的构造 那么必须⾃⼰定义出来 ⼀般开发如果 定义了有参的构造 都会再定义⼀个⽆参的构造
构造方法不能被 static、final、synchronized、abstract 和 native(类似于 abstract)修饰。构造方法用于初始化一个新对象,所以用 static 修饰没有意义。构造方法不能被子类继承,所以用 final 和 abstract 修饰没有意义。
构造函数的作用是创建一个类的实例。用来创建一个对象,同时可以给属性做初始化。当程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化。
JAVA集合
哪些集合类是线程安全的?
Vector、Hashtable、Stack 都是线程安全的,而像 HashMap 则是非线程安全的,不过在 jdk 1.5 之后随着 java.util.concurrent 并发包的出现,它们也有了自己对应的线程安全类,比如 HashMap 对应的线程安全类就是 ConcurrentHashMap。
list :LinkedList,ArrayList 和vector
LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全 ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全 Vector 接口实现类 数组, 同步, 线程安全
set:HashSet和TreeSet
HashSet 使用哈希表存储元素,元素可以是null LinkedHashSet 链表维护元素的插入次序 TreeSet 底层实现为红黑树,元素排好序,元素不可以是null
map:HashMap、TreeMap和HashTable
线程安全
HshaMap线程不安全 TreeMap线程不安全 HashTable线程安全
空值
HashMap一个null key,多个null value TreeMap不能null key,多个null value HashTable都不能有null
继承和接口
HashMap继承AbstractMap,实现接口Map TreeMap继承AbstractMap,实现接口NavigableMap(SortMap的一种) HashTable继承Dictionary,实现接口Map
顺序
HashMap中key是无序的 TreeMap是有序的 HashTable是无序的
构造函数
HashMap有调优初始容量和负载因子 TreeMap没有 HashTable有
数据结构
HashMap是链表+数组+红黑树 TreeMap是红黑树 HashTable是链表+数组
list、set和map的区别
list:元素按进入先后有序保存,可重复 set:不可重复,并做内部排序 map:代表具有映射关系的集合,其所有的key是一个Set集合,即key无序且不能重复。
Collection:单列集合的根接口
Map:双列集合的根接口,用于存储具有键(key)、值(value)映射关系的元素。
List:元素有序 可重复
● ArrayList:类似一个长度可变的数组 。适合查询,不适合增删 ● LinkedList:底层是双向循环链表。适合增删,不适合查询。
Set:元素无序,不可重复
● HashSet:根据对象的哈希值确定元素在集合中的位置 ● TreeSet: 以二叉树的方式存储元素,实现了对集合中的元素排序
LinkedHashSet继承于HashSet、又基于 LinkedHashMap 来实现
TreeSet使用二叉树的原理对新 add()的对象按照指定的顺序排序(升序、降序),每增加一个对象都会进行排序,将对象插入的二叉树指定的位置。
HashSet存储元素的顺序并不是按照存入时的顺序(和 List 显然不同) 而是按照哈希值来存的所以取数据也是按照哈希值取得
Set集合的底层是如何保证数据的不重复?
在往Set集合中添加对象的时候,首先会通过该对象的hashCode方法计算该对象的hash值。
如果该对象的hash值不存在,表示集合中不存在新的对象,将元素存入set集合中,如果hash值已经存在,则进一步的比较值是否相等,调用equals方法进行比较,如果值不相等,说明不是同一个对象,会将这个对象添加到已有对象的末尾。
总结:
新插入元素后,计算元素的hash值,如果计算的hash值在hash字典表中不存在,则为新插入的元素,插入 Set集合中,但是如果数据的hash值已经存在,在进行equal进行值的比较,如果值相等,插入失败,否则将对象插入源对象的链表尾部。
ArrayList与LinkedList的区别
● arrayList使用的是数组数据结构,可以以O(1)时间复杂度对元素进行随机访问;LinkedList使用的是(双)链表结构查找某个元素的时间复杂度是O(n) ● arrayList更适合于随机查找操作,linkedList更适合增删改查,时间复杂度根据数据浮动 ● 两者都实现了List接口,但LinkedList额外实现了Deque接口,因此Linked还可以当作队列使用 ● LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素
//遍历ArrayList
public static void main(String args[]){
List<String> list = new ArrayList<String>();
list.add("luojiahui");
list.add("luojiafeng");
//方法1
Iterator it1 = list.iterator();
while(it1.hasNext()){
System.out.println(it1.next());
}
//方法2
for(Iterator it2 = list.iterator();it2.hasNext();){
System.out.println(it2.next());
}
//方法3
for(String tmp:list){
System.out.println(tmp);
}
//方法4
for(int i = 0;i < list.size(); i ++){
System.out.println(list.get(i));
}
}
java面向对象
即封装继承多态 概论:面向对象是把一组数据结构和处理他们的方法组成对象; 把具有相同行为的对象归纳成类;通过封装隐藏类的内部细节;通过继承使类得到泛化; 通过多态实现基于对象类型的动态分派
吃饭: 面向过程:买菜,洗菜,做饭,洗手吃饭,洗碗 面向对象:点外卖,吃饭,扔外卖盒
封装:内部细节对外部调用透明 体现:1.JavaBean的属性私有,提供get set 对外访问,因为属性的赋值或者获取
Java的基础数据类型有哪些?(5分)
有布尔型 true false ,整数型long int byte short,字符类型char,浮点型float double
int 和 Integer 有什么区别?(5分)
Int 是基本数据类型,Integer是引用数据类型,Interger更多用于面向对象过程,即更多用于创建类过程中。
ArrayList和LinkedList有什么区别
ArrayList和LinkedList都实现了List接口,他们有以下的不通电 ArrayList是基于索引的数据接口,底层是数组,它可以以O(1)时间复杂度对元素进行随机访问。 对应的是LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,
总结: ArrayList基于数组,LinkedList基于链表
JAVA中的集合类
第一代线程安全集合类
Vector,Hashtable 是怎么保证线程安排的;使用synchronized修饰方法 缺点:效率低下
第二代线程非安全集合类
ArrayList ,HashMap 线程不安全,但是性能好,用来代替vector和Hashtable 使用ArrayList ,HashMap,需要线程安全怎么办呢? 使用Collections.synchronizedList(list);Collections.synchronizedMap(m); 底层使用synchronized代码块锁,虽然也是锁住了所有代码,
第三代线程安全集合类
在大量并发情况下如何提高集合的效率和安全呢
jdk1.8的新特性有哪些
接口的默认方法
java8允许我们给接口添加一个非抽象的方法实现,只需要使用default关键字即可,这个特征又叫做扩展方法, 示例如下: 代码如下: interface Formula{ double calculate(int a) default double sqrt(int a) { return Math.sqrt(a); } }
JAVA中抽象类和接口有什么区别
不同 抽象类: 1.抽象类中可以定义构造器 2.可以有抽象方法和具体方法 3.接口中的成员全都是public的 4.抽象类中可以定义成员变量 5.有抽象方法的类必须声明为抽象类,而抽象类未必要有抽象方法 6.抽象类中可以包含静态方法 7.一个类只能继承一个抽象类
接口: 1.接口中不能定义构造器 2.方法全都是抽象方法 3.抽象类中的成员可以是private,默认,protected,public 4.接口中定义的成员变量实际上是常量 5.接口中不能有静态方法 6.一个类可以实现多个接口
Java中==和equals有哪些区别
equals和==最大的区别是一个是方法一个是运算符
==:如果比较的对象时基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,则比较的是对象的地址值是否相等 equals(): 用来比较两个方法的内容是否相等。 注意:equals方法不能用于基本数据类型的变量,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向二代对象的地址。
● == : 对比的是栈中的值,基本数据类型是变量值,引用数据类型是堆中内存对象的地址; 直接比较的两个对象的堆内存地址,如果相等,则说明这两个引用实际是指向同一个对象地址的 ● equals:object中默认也是采用==比较,通常会重写
== 是java提供的等于比较运算符,用来比较两个变量指向的内存地址是否相同.而equals()是Object提供的一个方法.Object中equals()方法的默认实现就是返回两个对象==的比较结果.但是equals()可以被重写,所以我们在具体使用的时候需要关注equals()方法有没有被重写.
Java中重写和重载有哪些区别
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性,重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同,参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法生命更多的
String ,StringBuffer,StringBuilder区别及使用场景
Java平台提供了两种类型的字符串:String和StringBuilder,它们都可以存储和操作字符串,区别如下。
1.String是只读字符串,也就意味着String引用的字符串内容是不能被改变的,初学者可能会有这样的误解:
String str ="abc";
str = "bad"
如上,字符串str命名是可以改变的吖!其实不然,str仅仅是一个是一个引用对象,它指向一个字符串对象“abc”, 第二行代码的含义是让str重新指向一个新的字符串"bcd"对象,而“abc”对象并没有任何改变,只不过该对象已经成为了一个不可及对象罢了
2.StringBuffer/StringBuffer表示的字符串对象可以直接修改 3.StringBuffer是java5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方法都没有被synchronized修饰,因此它的效率理论上也比StringBuffer要高。
Redis
Redis线程模型有哪些,单线程为什么快
JAVA中的数据结构
Java哈希表
hashCode() 和equals()方法的重要性体现在上面地方?
Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法的实现对HashMap的精确性和正确性是至关重要的。
请说一说,Java中的HashMap的工作原理是什么?
HashMap是以键值对的形式存储元素的,需要一个哈希函数,使用hashcode和eaquels方法,从集合中添加和检索元素,调用put方法时,会计算key 的哈希值,然后把键值对存在集合中合适的索引上,如果键key已经存在,value会被更新为新值。另外HashMap的初始容量是16,在jdk1.7的时候底层是基于数组和链表实现的,插入方式是头插法。jdk1.8的时候底层是基于数组和链表/红黑树实现的,插入方式为尾插法。
介绍一下,什么是hashmap?
HashMap 是一个散列表,它存储的内容是键值对(key-value)。 HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。 HashMap 的实现不是同步的,所以它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。 HashMap 的实例有两个参数影响其性能:“初始容量” 和 “负载因子”。容量 是哈希表中桶的数量,初始容量 只是哈希表在创建时的容量。负载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。 通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。 HashMap在扩容的时候是2的n次幂。
HashMap和LinkedHashMap的区别?
HashMap,LinkedHashMap,TreeMap都属于Map
Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许键重复,但允许值重复。
HashMap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。
LinkedHashMap LinkedHashMap也是一个HashMap,但是内部维持了一个双向链表,可以保持顺序
TreeMap 可以用于排序
HashMap的例子
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("a3", "aa");
map.put("a2", "bb");
map.put("b1", "cc");
for (Iterator iterator = map.values().iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
System.out.println(name);
}
}
输出:bbccaa
LinkedHashMap例子:
public static void main(String[] args) {
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("a3", "aa");
map.put("a2", "bb");
map.put("b1", "cc");
for (Iterator iterator = map.values().iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
System.out.println(name);
}
}
输出: aa bb cc
总结归纳为:linkedMap在于存储数据你想保持进入的顺序与被取出的顺序一致的话,优先考虑LinkedMap,hashMap键只能允许为一条为空,value可以允许为多条为空,键唯一,但值可以多个。
经本人测试linkedMap键和值都不可以为空
HashMap和HashTable有什么区别?
1、HashMap是非线程安全的,HashTable是线程安全的。 2、HashMap的键和值都允许有null值存在,而HashTable则不行。 3、因为线程安全的问题,HashMap效率比HashTable的要高。 4、Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。 一般现在不建议用HashTable: ①是HashTable是遗留类,内部实现很多没优化和冗余。 ②即使在多线程环境下,现在也有同步的ConcurrentHashMap替代,没有必要因为是多线程而用HashTable
final关键字在Java中有什么作用?
可用来修饰类,方法,变量
1.final修饰变量,则等同于常量 2.final修饰方法中的参数,称为最终参数。
3.final修饰类,则类不能被继承 (太监类)
4.final修饰方法,则方法不能被重写。5.final 不能修饰抽象类
6.final修饰的方法可以被重载 但不能被重写 (不能继承)
- 当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类
- 使用final方法的原因有两个:第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最