大家好,又见面了,我是你们的朋友全栈君。
1.Object类
1.1toString()
重写toString()方法
@Override
public String toString() {
return "这是只一个学习测试而已";
}
1.2equals()
Object类的equals方法默认是比较两个对象的地址值,没有意义。
所以我们要重写equals方法,比较两个对象的属性。
重写equals方法
@Override
public boolean equals(Object obj) {
T1 t= (T1)obj;//向下转型
return super.equals(obj);
}
增加判断,防止类型转换异常ClassCastException
@Override
public boolean equals(Object obj) {
//增加一次判断提高效率(如果类是null)
if (obj!=null){
return false;
}
//增加一次判断提高效率(如果是一样的类)
if(obj==this){
return true;
}
if(obj instanceof T1){
T1 t= (T1)obj;//向下转型
return true;
}
return false;
}
Objects类(1.7之后添加的工具类)
JDK提供了一些方法来操控对象,它由一堆静态实用方法组成,这些方法都是null-save(空指针安全)或null-tolerant(容忍空指针的),用于计算对象的hashcode、返回对象字符串表达形式、比较两个对象。
- public static boolean equlas(Object a, Object b);判断两个对象是否相等
- getClass() !=o.getClass()使用反射技术,判断o是否是原类型 类似于obj instanceof T1
2.Date类
java.utill.Date:表示日期和时间的类。
Date 表示特定的瞬间,精确到毫秒。
毫秒:千分之一秒 1000毫秒=1秒
毫秒值的作用:可以对时间和日期进行计算。
可以日期转换为毫秒进行计算,计算完毕,将毫秒转换成日期
时间原点(0毫秒):1970年1月1日00:00:00(英国格林威治)
就是计算当前日期到时间原点之间一共经历了多少毫秒(1617106265245)
注意
中国属于东八区,会把时间增加8个小时
1970年1月1日00:00:00
把毫秒转换为日期
1天=24×60×60=86400秒=86400×86400000毫秒
Date类空参数构造方法
Date()获取当前日期和时间
使用情况:
public static void date(){
System.out.println(System.currentTimeMillis());
Date d = new Date();
System.out.println(d);
}
运行效果
Date类带参构造方法
Date(Long date)传递毫秒值,把毫秒值转换为Date值
使用情况:
public static void date1(){
Date d1=new Date(0L);
System.out.println(d1);
Date d2=new Date(1617106265245L);
System.out.println(d2);
}
运行情况:
Long getTime()把日期转换为毫秒值(相当于System.currentTimeMillis()方法)
返回自1970年1月1日 00:00:00 GMT以来过了多少毫秒数。
2.2DateFormat类
java.text.DateFormat是日期/时间格式画子类的抽象类。
作用:格式化(日期->文本)、解析(文本->日期)
成员方法:
- String format(Date date)按照指定的模式,格式化为符合模式的字符串
- Date parse(String source) 把符合模式的字符串,解析为Date日期
DateFormat类是一个抽象类,无法直接创建对象使用,可以直接使用DateFormat的子类java.text.SimpleDateFormat
构造方法:
SimpleDateFormat(String pattern)
用给定的模式和默认语言环境的日期格式符号和构造SimpleFormat。
参数模式区分大小写:
- y 年
- M 月
- d 日
- H 时
- m 分
- s 秒
写对应的模式,会把模式替换为对应的日期和时间
”yy年MM月dd日 HH时mm分ss秒“
使用情况:
private static void dateFormat() {
SimpleDateFormat df=new SimpleDateFormat("yy年MM月dd日HH时mm分ss秒");
Date d=new Date();
String format = df.format(d);
System.out.println(format);
}
运行情况:
使用DateFormat类中的方法parse,把文本解析为日期
public Date parse(String source)throws ParseException
parse方法声明了一个异常叫ParseException,如果字符串和构造方法的模式不一样,那么程序就会抛出异常。
使用情况:
private static void dateFormat2() {
SimpleDateFormat df=new SimpleDateFormat("yy年MM月dd日HH时mm分ss秒");
Date format = null;
try {
format = df.parse("2021年03月31日13时58分12秒");
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(format);
}
运行情况:
2.3练习
计算一个人从出生到现在一共活了多少天
//练习:使用日期计算出一个人已经出生了多少天
private static void test() {
Scanner sc =new Scanner(System.in);
System.out.println("输入你的出生日期:yyyy年MM月dd日");
String day=sc.next();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
Date dp=null;
try{
dp=sdf.parse(day);
}catch (Exception e){
e.printStackTrace();
}
Date d = new Date();
//把转换的日期转换成毫秒值
long time1 = dp.getTime();
long time2 = d.getTime();
long time = time2 - time1;
long td=time/1000/60/60/24;
System.out.println("宁已经活了"+td+"天,可以考虑什么时候去世了!");
}
运行结果:
2.4Calendar类(日期与时间处理)
使用情况:
public static void main(String[] args){
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) +1;
int day = c.get(Calendar.DATE);
int week = c.get(Calendar.DAY_OF_WEEK) -1;
System.out.println("今天是"+year+"年 "+month+"月 "+day+"日 星期"+week);
}
运行效果
Calendar 的静态变量
YEAR get现场编号和 set表示年份。
MONTH get和 set字段号表示月份。
DAY_OF_MONTH get字段编号和 set本月的日期。
DAY_OF_WEEK get字段编号和 set表示一周中的日期。
DAY_OF_YEAR get和 set字段编号, set本年度的日数。
WEEK_OF_YEAR get和 set字段编号, set本年度的周数。
WEEK_OF_MONTH get和 set字段编号, set当月的周数。
3System类
java.lang.System类中提供了大量的静态方法
- public static long currentTimeMillis():返回以毫秒为单位的当前时间
- public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int lenght):将数组中指定的数据拷贝到另一个数组中。
参数
src-源数组
srcPos-源数组中的起始位置(起始索引)
dest-目标数组
destPost-目标数组中的起始位置
length-要复制的数组长度
使用情况:
private static void test1() {
int[] a={1,2,3,4};
int[] b={5,6,7,8};
System.out.println("复制前"+ Arrays.toString(b));
System.arraycopy(a,0,b,1,3);
System.out.println("复制后"+ Arrays.toString(b));
}
运行结果:
4StringBuilder类
为神马要经常用StringBuilder
String类 字符串是常量,它的值在创建之后不能更改。
字符串的底层是一共被final修饰的数组,不能改变,是一个常量
- private final byte[] value;
进行字符串的相加,内存中就会有多个字符串,占用空间多,效率低下。
如:String s= “a”+“b”+“c”; 中会产生5个字符串
“a” “b” “c”三个字符串 “ab”一个字符串 “abc”一个字符串
java.lang.StringBuilder类
字符串缓冲区,可以提高字符串的操作效率(看成一个长度可以变化的字符串)
底层也是一个数组,但是没有被final修饰,可以改变长度
- byte[] value = new byte[16];
StringBuilder在内存中始终是一个数组,占用空间小,效率高
如果超出StringBuilder的容量,会自动扩容
构造方法
StringBuilder()构造一个不带任何字符的字符生成器,其初始容量为16个字符
StringBuilder(String str)构造一个字符串生成器,并初始化为指定的字符串内容。
常用方法
public StringBuilder append(…);添加任意类型数据的字符串形式,并返回当前自身。
public String toString();将当前StringBuilder对象转换为String对象
5包装类
Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。基本类型的数据不具备”对象”的特性(没有成员变量和成员方法可以调用),因此,java为每种数据类型分别设计了对应的类,即包装类。
5.2装箱与拆箱
装箱:把基本类型的数据,包装到包装类中(基本类型的数据->包装类)
构造方法:
Integer(int value)构造一个新分配的Integer对象,它表示指定的int值
Integer(String s)构造一个新分配的Integer对象,他表示String参数所指示的int值。
静态方法:
static Integer valueOf(int i)返回一个表示指定的int值的Integer实例。
static Integer valueOf (String s)返回保存指定的String的值的Integer对象
拆箱:在包装类中取出基本类型的数据(包装类->基本类型的数据)
成员方法:
int intValue() 以int 类型返回该Integer的值
5.3自动装箱与自动拆箱
自动装箱与自动拆箱:基本类型的数据和包装类之间可以自动的相互转换(JDK1.5之后出现的新特征)
比如:
- (自动装箱)Integer in=1;相当于Integer in =new Integer(1);
- (自动拆箱)in + 2就相当于in.intValue() + 2 =3;
- ArrrayList集合无法直接储存整数,可以储存Integer包装类,list.add(1);->自动装箱list.add(new Integer(1))
- int a = list.get(0);->自动拆箱 list.get(0).intValue();
5.4基本类型与字符串类型之间的相互转换
基本类型->字符串
- 基本类型值+””
- 包装类的静态方法toString(参数),不是Object类的toString()重载。
static String toString(int i) - String类的静态方法valueOf(参数)
static String valueOf(int i)返回int参数的字符串表达形式
字符串(String)->基本类型
- 使用包装类的静态方法parseXXX(“字符串”);
- Integer类:static int parseInt(String s)
- Double类:static double parseDouble(String s)
6Collection集合
集合:集合是java中提供的一个容器,可以用来储存多个数据
- 数组长度是固定的,集合长度是可变的。
- 数组中储存的是同一类型的元素,可以储存基本数据类型值,集合储存的都是对象,对象类型可以不一致。
集合按照储存结构可以分为两大类,分别是单列集合java.util.Collection和双列集合java.util.Map。
共性方法:
- public boolean add(E e);把给定的对象添加到当前集合中。
- public void clearI();清空集合中所有的元素。
- public boolean remove(E e);把给定的对象在当前集合中删除。
- public boolean contains(E e);判断当前集合中是否包含给定的对象。
- public boolean isEmpty();判断当前集合是否为空。
- public int size();返回集合中元素的个数。
- public Object[] toArray();把集合中的元素,储存到数组中。
6.1Iterator接口
java.util.Iterator对Collection进行迭代的迭代器
两个常用方法:
- boolean hasNext();如果仍有元素可以迭代,则返回true
- E next();返回迭代的下一个元素
Collection接口中有一个方法,叫iterator(),这个方法返回的就是迭代器的实现类对象
- Iterator iterator()返回在此collection的元素上进行迭代的迭代器
使用情况:
private static void test2() {
Collection<String> list=new ArrayList<>();
list.add("11");
list.add("22");
list.add("33");
list.add("44");
Iterator<String> it= list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
运行情况:
Iterator实现原理:
- Collection.iterator();获取迭代器的实现类对象,并且会把指针(索引)指向集合的-1索引
- it.next();取出下一个元素,会把指针向后移动一位
6.2增强for
增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,用来专门来遍历数组和集合的。它内部原理其实也是一个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
Collection extends Iterable;所有的单列集合都可以使用增强for
public interface Iterable 实现这个接口允许成为“foreach”语句的目标
格式:for(集合/数组的数据类型 变量名:集合名/数组名)
7.泛型
泛型:是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型
泛型也可以看出是一个变量,用来接收数据类型
E e:Element 元素
T t:Type 类型
创建集合对象,不使用泛型的
好处:
- 集合不使用泛型,默认的类型就是Object类型,可以储存任意类型的数据
弊端:
- 不安全,会引发异常
创建集合对象,使用泛型
好处:
- 避免类型转换的麻烦,储存是什么什么类型,取出就是什么类型。
- 把运行期异常,提升到了编译器(写代码的时候会报错)
弊端:
- 泛型是什么类型,只能储存什么类型的数据
泛型的定义与使用
例如:
public class T3<E> {
public E e;
public E get(){
return e;
}
public void set(E e){
this.e=e;
}
}
定义泛型方法
例如:
public <M> void test3(M m){
System.out.println(m);
}
含有泛型的接口
例如:
public interface T4 <E>{
public void test(E e);
}
含有泛型的接口有两种实现方式。
第一种实现方式:定义接口的实现类,实现接口,指定接口的类型
public interface Iterator<E>{
E.next();
}
Scanner类实现了Iterator接口并指定接口的泛型为String,所以重写的next方法泛型默认是String
public final class Scanner implements Iterator<String>{
public String next(){ }
}
第二种实现方式:接口使用什么类型,实现类就使用什么类型,类跟着接口走
public class ArrayList<E> implements List<E>{
public boolean add(E e){ }
public E get(int index){ }
}
泛型的通配符
不知道使用什么类型来接受的时候,就可以使用?,?表示未知通配符
定义一个方法,能遍历所有类型的ArrayList集合
这时候我们不知道ArrayList集合使用什么的数据类型,可以泛型的通配符?来接受数据类型
public static void printArray(ArrayList<?> list){
//使用迭代器迭代
Iterator<?> it =list.iterator();
while (it.hasNext()){
Object obj = it.next();
System.out.println(obj);
}
}
泛型的高级使用-受限泛型
泛型上限: ? extends E 代表使用的泛型只能是E的子类
泛型下线: ? super E 代表使用的泛型只能是E的父类
扑克牌发牌训练题
ArrayList<String> list = new ArrayList<>();
list.add("大王");
list.add("小王");
String[] a={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
String[] b={"♥","♠","♦","♣"};
ArrayList<String> wang = new ArrayList<>();
ArrayList<String> zhang = new ArrayList<>();
ArrayList<String> li = new ArrayList<>();
ArrayList<String> last = new ArrayList<>();
for (String s : b) {
for (String s1 : a) {
list.add(s+s1);
}
}
Collections.shuffle(list);
for (int i =0;i<list.size();i++){
if (i>=51){
last.add(list.get(i));
}else if (i%3==0){
wang.add(list.get(i));
}else if(i%3==1){
zhang.add(list.get(i));
}else if(i%3==2){
li.add(list.get(i));
}
}
System.out.println("小王手中的牌是"+wang);
System.out.println("小张手中的牌是"+zhang);
System.out.println("小李手中的牌是"+li);
System.out.println("底牌是"+last);
运行结果:
8数据结构
8.1栈stack又称堆栈(先进后出)
8.2队列queue(先进先出)
8.3数组Array(1查询快:数组地址是连续的;增删慢:数组长度是固定的,我们需要创建一个新数组,再把数组的数值复制过来。在堆内存中频繁创建数组,复制数组中的元素,销毁数组,效率低下)
链表linked list(查询慢:链表中的地址不是连续的,每次查询都必须从头查询;增删快:链表结构,增加/删除元素,对链表结构没有影响)
- 单向列表:链表中有一条链子,不能保证元素的顺序
- 双向列表:链表中有两条链子,是一个有序的集合
排序树/查找树左子树小,右子树大
平衡树左孩子和右孩子相等
不平衡树左孩子和右孩子不相等
红黑树特点:趋近于平衡树,查询速度非常快,查询叶子节点最大次数和最小次数不能超过2倍。
约束
3. 节点可以是红色的或者黑色的
4. 根节点是黑色的
5. 叶子节点(空节点)是黑色的
6. 每个红色的节点的子节点都是黑色的
7. 任何一个节点刀其每一个叶子节点的所有路径上黑色节点数相同
List集合
java.util.list接口extends Collection接口
List接口的特点:
- 有序的集合,储存顺序和取出顺序一致
- 有索引,包含带索引的方法
- 允许储存重复的元素
List接口中带索引的方法
- public void add(int index, E element);
- public E get(int index);返回指定位置的元素
- public E remove(int index);移除指定位置的元素,返回的是被移除的元素
- public E set(int index,E element);用指定元素替换集合中指定位置的元素,返回值是更新前的元素
IndexOutOfBoundsException:索引越界异常,集合汇报
ArrayIndexOutOfBoundsException:数组索引越界异常
StringOutOfBoundsException:字符串索引越界异常
ArrayList(多线程)
底层是数组,查询快增删慢
LinkeList集合
List的链表结构,查询慢,增删快v
java.utill.LinkedList集合 implements List接口
LinkedList集合贴点:
- 底层是一个链表结构查询慢,增删快
- 里面包括了大量操作首位元素的方式
注意使用LinkedList集合特有的方法不能使用多态
常用方法
- public void addFirst(E e):将指定元素插入此列表的开头
- public void addLast(E e):将指定元素添加到此列表结尾//等效于add(E e);
- public void push(E e);将元素推入此列表所表示的堆栈//等效于addFirst(E e);
- public E getFirst();返回列表第一个元素
- public E getLast();返回元素最后一个元素
- public E removeFirst();移除并返回此列表第一个元素;
- public E removeLast();移除并返回此列表最后一个元素
- public‘ E pop();从此列表所表示的堆栈处弹出一个元素。//等效于移除第一个元素removeFirst();
- public boolean isEmpty();如果列表不包含元素,则返回true
- linked.clear();//清空集合中的元素,在获取元素中的元素会抛NoSuchElementException
Vector
可以实现可增长的对象数组(底层数组,单线程,实现了List接口)
接口Set
java.util.Set接口 extends Collection
- 不允许储存重复的元素
- 没有索引,没有带索引的方法,也不能使用普通的for循环遍历
HashSet
java.util.HashSet
- 不允许储存重复的元素
- 没有索引,没有带索引的方法,也不能使用普通的for循环遍历
- 是一个无序的集合,储存元素和取出元素的顺序可能不一致
- 底层是一个哈希表结构(查询速度非常快)
哈希表
哈希值是一个十进制的整数,由系统随机给出(就是对象的地址,是一个逻辑地址,是模拟出来得到的类,不是数据实际储存的物理地址)
Object类有一个方法可以获取对象的哈希值 int hashCode()返回对象的哈希码值。
- public native int hashCode();
- native :代表该方法调用的是本地操作系统的方法
Object中toString方法源码
- return getClass().getName()+”@”+Integer.toHexString(hasCode());
HashSet集合储存数据的结构(哈希表)
- jdk1.8版本之前:哈希表=数组+链表;
- jdk1.8版本之后:数组+红黑树(提高查询的速度)
- 把元素进行分组(相同哈希值元素是一组)链表/红黑树(挂的元素超过8位) 初始容量为16
Set储存元素不重复的原理:Set集合在调用add方法的时候,add方法会调用元素的hashCode方法和equals方法判断元素是否重复
储存的元素必须重写hashCode方法和equals方法
LinkedHashSet(继承了HashSet)
LinkedHashSet特点:
- 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的储存顺序),保证元素有序。
9可变参数
在jdk1.5之后出现的型特性
使用前提:
- 网方法的参数数据类型已经确定,但是参数个数不确定,就可以使用可变参数
可变参数原理:
- 可变参数底层就是一个数组,根据传递的参数个数不同,就会创建不同长度的数组,传递的参数个数,可以是0个(不传递),1,2…多个
例:
public static int add(int ... arr){
return 0;
}
可变参数注意事项:
- 一个方法的参数列表,只能有一个可变参数
- 如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
Collections
java.utils.Collections是集合工具类常用功能:
public static<T> boolean addAll(collection<T> c,T... elemnets):往元素中添加一些元素
public static void shuffle(List<?> list)打乱顺序 : 打乱集合顺序
public static <T> void sort (List<T> list):将集合中元素按照默认规则排序
public static <T> void sort(List<T> list,Comparator<? super T>);将集合中元素按照指定顺序排序
注意:
sort(List list)使用前提:被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序
public class T5Collections implements Comparable<T5Collections> {
public int index;
@Override
public int compareTo(T5Collections t) {
return this.index - t.index;//升序排序
}
}
第二种方法
public static void main(String[] args) {
T5Collections t1=new T5Collections();
T5Collections t2=new T5Collections();
T5Collections t3=new T5Collections();
T5Collections t4=new T5Collections();
t1.index=5;
t2.index=1;
t3.index=6;
t4.index=5;
ArrayList<T5Collections> list =new ArrayList<>();
// HashSet<T5Collections> list =new HashSet<>();
Collections.addAll(list,t1,t2,t3,t4);
Collections.sort(list, new Comparator<T5Collections>() {
@Override
public int compare(T5Collections o1, T5Collections o2) {
return o1.index-o2.index;
}
});
System.out.println(list);
}
10Map
将键映射到对象的值,一个映射不能包括重复的键,每个键最对映射一个值。
java.util.Map<k,v>集合
Map集合的特点:
- Map集合是一个双列集合,一个元素包含两个值(一个key,一个value)
- Map集合中的元素,key和value的数值类型可以相同,也可以不同
- Map集合中的元素,key是不允许重复的,value是可以重复的
- Map集合中的元素,key和value是一一对应的·
常用子类
- HashMap 无序集合,多线程速度快
- LinkedHashMap 有序集合
java.util.HashMap implements Map<k,v>
HashMap特点:
- jdk1.8之前,数组+单向列表;jdk1.8之后数组+单向列表/红黑树
- hashMap是一个无序集合,储存元素和取出顺序可能不一致
java.util.LinkedMap集合特点:
- LinkedHashMap集合底层是哈希表+链表(保证迭代顺序)
- LinkedHashMap集合是一个有序的集合,储存顺序和取出顺序一样
Map常用方法:
- public v put(k key,v value):把指定的键与指定方向的键添加到Map集合中
返回值v,储存键值对的时候,key重复就会返回被替换的value值,反之null
- public v remove (Object key):把指定的键所对应的键值对元素在Map集合中删除,返回被删除元素的值
- public v get(Object key)根据指定的键,在Map集合中获取对应的值。
- boolean contains Key(Object key)判断集合中是否包含指定的键
- public Set<k> keySet();获取Map集合中所有的键,存储到Set集合中
- public Set<Map.Entry<k,y>> entrySet();获取到Map集合中所有键值对对象的集合(Set集合)
Entry
Map.Entry<k,v>;在Map接口中有一个内部接口Entry
作用:当Map集合一创建,那么就会在Map集合中创建一个Entry对象,用来记录键与值(键值对对象,键与值的映射关系)
HashMap储存自定义类型键值:Map结合保证key是唯一的:作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一;
LinkedHashMap
java.util.LinkedHashMap<k,v> extends HashMap<k,v>
Map接口的哈希表和链接链表实现,,具有可预知的迭代顺序
底层原理:
哈希表+链表(记录元素顺序)
Hashtable<K,V>
任何非null对象都可以用作键或值
单线程慢,线程安全
Hashtable和Vector集合一样,在jdk1.2版本之后被更先进的集合(HashMap,ArrayList)取代了
Hashtable的子类Prorerties依然活跃
Proreties集合是唯一和IO流相结合的集合
11JDK9对集合添加的优化
List接口、Set接口、Map接口:里面添加了一个静态方法of,可以给集合一次性添加多个属性
- static < E > List< E > of (E…elements)
使用前提:当集合中储存的元素的个数已经确定了,不在改变使用
注意:
- of方法只适用List接口、Set接口、Map接口,不适用于接口的实现类
- of方法的返回值是一个不能改变的集合,集合不能再使用add、put方法添加元素,会抛出异常
- set接口和Map接口在调用of方法的时候,不能由有重复的元素,否则会抛出异常
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/156886.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...