Java学习笔记
- 一.1 转义字符
- 一.2 相对路径与绝对路径
- 一.3 注释
- 二.1 数据类型
- 二.2 浮点型的注意事项
- 二.3 char类型的注意事项及编码
- 二.4 boolean注意事项
- 二.5 自动类型转换
- 二.6 强制类型转换
- 二.7 String和基本数据类型转换
- 三 Scanner输入
- 四.1 逻辑运算符
- 四.2 复合运算符
- 四.3 三元运算符
- 四.4 位运算符
- 五 命名规范
- 六.1 多分支使用
- 六.2 循环
- 七.1 数组的定义以及初始化
- 七.2 数组的拷贝以及扩容
- 七.3 二维数组
- 八.1 类与对象
- 八.2 重载
- 八.3可变参数
- 八.4 构造器
- 八.5 this
- 八.6 封装
- 八.7.1 继承
- 八.7.2 访问修饰符
- 八.7.3 super()用法
- 八.7.4 方法重写
- 八.8.1 多态(向上/向下转型)
- 八.8.2 动态绑定机制
- 八.8.3 多态小结
- 八.9 object类
- 八.10 hashCode
- 八.11 toString()
- 八.12 finalize
- 八.13 类变量和类方法(static)
- 八.14 main()方法
- 八.15 代码块
- 八.16 final
- 八.17 单例设计模式
- 九.1 抽象类
- 九.2 接口
- 十.1 局部内部类
- 十.2 匿名内部类
- 十.3 成员内部类
- 十.4 静态内部类
- 十一.1 枚举
- 十一.2 Enum类方法
- 十二 注解
- 十三.1 异常-(try-catch)
- 十三.2 throws
- 十四 Arrays方法
- 十五 Stack方法
- 十六 idea快捷键
- 十七 包装类
- 十八.1 String类
- 十八.2 String类常用方法
- 十八.3 StringBuffer
- 十八.4 StringBuffer方法
- 十九 Math类方法
- 二十 System类
- 二十一.1 BigInteger类
- 二十一.2 BigDecimal类
- 二十二.1 日期类—Date类
- 二十二.2 日期类—Calendar类
- 二十二.3 LocalDateTime
- 二十三.1 集合
- 二十三.2 Collection
- 二十三.3 List
- 二十三.4 ArrayList和Vector
- 二十三.5 LinkedList
- 二十三.6 Set
- 二十三.7 HashSet
- 二十三.8 LinkedHashSet
- 二十三.9 Map
- 二十三.10 HashMap
- 二十三.11 Hashtable
- 二十四 Collections工具类
- 二十五.1 泛型
- 二十五.2 自定义泛型类
- 二十五.3 自定义泛型接口
- 二十五.4 自定义泛型方法
- 二十五.5 泛型的继承和通配符
- 二十六 JUnit使用
一.1 转义字符
一.2 相对路径与绝对路径
一.3 注释
用快捷键ctrl+/添加注释
多行注释不可以嵌套
———————————————————————
二.1 数据类型
二.2 浮点型的注意事项
注意:浮点型为近似值,在进行判断时需要进行相减小于一个极小值即可!
二.3 char类型的注意事项及编码
二.4 boolean注意事项
此处跟C++不同,不同用0或者非0替代false和true
二.5 自动类型转换
需要注意,当byte,short,int三者计算时,首先先转换为int类型。
二.6 强制类型转换
是高精度->低精度
eg:int n = (int)(10*3.5+1);
二.7 String和基本数据类型转换
三 Scanner输入
四.1 逻辑运算符
四.2 复合运算符
此处需要注意,复合运算符会进行类型转换!
四.3 三元运算符
四.4 位运算符
五 命名规范
六.1 多分支使用
六.2 循环
七.1 数组的定义以及初始化
七.2 数组的拷贝以及扩容
七.3 二维数组
八.1 类与对象
注意:属性有默认值,局部变量无默认值!
八.2 重载
1.方法名相同
2.形参列表必须不同(类型,个数,顺序),参数名无要求
3.返回类型无影响!
八.3可变参数
八.4 构造器
八.5 this
八.6 封装
八.7.1 继承
八.7.2 访问修饰符
八.7.3 super()用法
八.7.4 方法重写
八.8.1 多态(向上/向下转型)
八.8.2 动态绑定机制
八.8.3 多态小结
八.9 object类
八.10 hashCode
八.11 toString()
八.12 finalize
八.13 类变量和类方法(static)
八.14 main()方法
八.15 代码块
八.16 final
八.17 单例设计模式
九.1 抽象类
九.2 接口
十.1 局部内部类
十.2 匿名内部类
十.3 成员内部类
十.4 静态内部类
十一.1 枚举
十一.2 Enum类方法
十二 注解
十三.1 异常-(try-catch)
十三.2 throws
十四 Arrays方法
此处补充一下sort的定制排序
当return i1-i2;是从小到大排序
当return i2-i1;是从大到小排序
//sort,定制排序
Integer[] arr = {1,2,5,4,9,5,7};
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
Integer i1 = (Integer) o1;//向下转型
Integer i2 = (Integer) o2;
//从小到大排序
//return i1-i2;
//从大到小排序
return i2-i1;
}
});
代码实现:
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
/**
* @author ZHR
* @version 1.0
**/
public class ArraysMethod {
public static void main(String[] args) {
//toString
Integer[] integer = {1,2,30,40,2,5,7};
System.out.println(Arrays.toString(integer));
//sort,此处数组是引用类型,sort会直接修改原内容
Arrays.sort(integer);
System.out.println(Arrays.toString(integer));
//sort,定制排序
Integer[] arr = {1,2,5,4,9,5,7};
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
Integer i1 = (Integer) o1;//向下转型
Integer i2 = (Integer) o2;
//从小到大排序
//return i1-i2;
//从大到小排序
return i2-i1;
}
});
//冒泡排序
int[] arr1 = {9,8,7,6,5};
bubbleSort(arr1);
System.out.println(Arrays.toString(arr1));
//binarySearch 此处要求binarySeach是有序的!找不到返回-(low+1)
Integer[] arr2 = {1,2,3,4,5};
System.out.println(Arrays.binarySearch(arr2,5));
//copyof 如果拷贝长度大于arr2.length,就插入null
Integer[] arr3 = Arrays.copyOf(arr2,3);
System.out.println(Arrays.toString(arr3));
//fill
Integer[] arr4 = new Integer[]{1,2,3};
Arrays.fill(arr4,99);
System.out.println(Arrays.toString(arr4));
//equals 比较两个数组元素是否完全一致
System.out.println(Arrays.equals(arr,arr2));
//asList 转换成list
List asList = Arrays.asList(arr);
System.out.println(asList);
}
public static void bubbleSort(int[] arr) {
for (int i = arr.length - 1; i > 0; i--) {
boolean flag = true;
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
}
}
if(flag) break;
}
}
}
练习:生成一个book类,属性有名字和价格
1.按照book价格排序(从大到小,从小到大)
2.按照书名的长度排序
import java.util.Arrays;
import java.util.Comparator;
/**
* @author ZHR
* @version 1.0
**/
public class ArraysHomework {
public static void main(String[] args) {
Book[] books = new Book[4];
books[0] = new Book("红楼梦和西游记",100);
books[1] = new Book("金平梅第二",90);
books[2] = new Book("青年文摘",5);
books[3] = new Book("jav",300);
//从小到大排序
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Integer num1 = (Integer) o1.price;
Integer num2 = (Integer) o2.price;
return num1-num2;
}
});
System.out.println(Arrays.toString(books));
//从大到小排序
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Integer num1 = (Integer) o1.price;
Integer num2 = (Integer) o2.price;
return num2-num1;
}
});
System.out.println(Arrays.toString(books));
//按照书名长度排序
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Integer num1 = (Integer) o1.name.length();
Integer num2 = (Integer) o2.name.length();
return num1-num2;
}
});
System.out.println(Arrays.toString(books));
}
}
class Book{
String name;
int price;
public Book(String name, int price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
十五 Stack方法
十六 idea快捷键
十七 包装类
十八.1 String类
两种方式的练习题:
String s = "hsp";
String s1 = new String("hsp");
System.out.println(s==s1);//false 比较的是地址
System.out.println(s.equals(s1));//true 比较的是String的value
System.out.println(s==s1.intern());//intern()用法是返回常量池中与s1的value相同的常量的地址,也就是a
System.out.println(s1==s1.intern());//同上
十八.2 String类常用方法
代码:
//equalsIgnoreCase
String s1 = "abc";
String s2 = "ABC";
System.out.println(s1.equalsIgnoreCase(s2));
//indexOf
String s = "1234";
int n1 = s.indexOf('1');
System.out.println(n1);
//lastIndexOf
String s3 = "12344321";
int n2 = s3.lastIndexOf('1');
System.out.println(n2);
//subString
String s4 = s3.substring(0,4);
System.out.println(s4);
String s5 = s3.substring(2);
System.out.println(s5);
//toCharArray
char[] ch = s5.toCharArray();
for(char c : ch) System.out.print(c+" ");
//toUpperCase
System.out.println(s5.toUpperCase());
//toLowerCase
String s6 = "HELLO";
System.out.println(s6.toLowerCase());
//compareTo
String s7 = "bcdeabc";
String s8 = "bcde";
System.out.println(s7.compareTo(s8));
十八.3 StringBuffer
十八.4 StringBuffer方法
StringBuffer stringBuffer = new StringBuffer("123");
//append
stringBuffer = stringBuffer.append("134").append("99");
//length and capacity
System.out.println(stringBuffer.length());
System.out.println(stringBuffer.capacity());
//delete
stringBuffer.delete(0,3);
System.out.println(stringBuffer);
//replace
stringBuffer.replace(0,3,"jack");
System.out.println(stringBuffer);
//insert
stringBuffer.insert(0,"1");
System.out.println(stringBuffer);
//setCharAt
stringBuffer.setCharAt(0,'z');
System.out.println(stringBuffer);
//reverse
stringBuffer.reverse();
System.out.println(stringBuffer);
//deleteCharAt()
stringBuffer.deleteCharAt(0);
System.out.println(stringBuffer);
作业:格式化价格
//12345 -> 12,345 价格格式化
String price = "134232415.56";
StringBuilder p = new StringBuilder(price);
int i = p.lastIndexOf(".");
i -=3;
while(i>0) {
p.insert(i, ",");
i -= 3;
}
System.out.println(p);
十九 Math类方法
//abs
int abs = Math.abs(-1);
System.out.println(abs);
//pow
double pow = Math.pow(2,5);
System.out.println(pow);
//ceil
double ceil = Math.ceil(5.1);
System.out.println(ceil);
//floor
double floor = Math.floor(5.1);
System.out.println(floor);
//round
long round = Math.round(5.3);
System.out.println(round);
//sqrt
double sqrt = Math.sqrt(9);
System.out.println(sqrt);
二十 System类
1.exit(0) 0表示一个状态,正常退出的状态
System.out.println("程序开始");
//System.exit(0);
System.out.println("程序退出");
2. arraycopy 一般用Arrays.copyOf即可
System.arraycopy(原数组,原数组起始下标,目标数组,目标数组起始下标,拷贝个数)
int[] src = {1,2,3};
int[] dest = new int[3];
System.arraycopy(src,0,dest,0,3);
System.out.println(Arrays.toString(dest));
3.currentTimeMillis 返回距离1970-1-1的毫秒数 返回值为 long
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
System.out.println("用时为:"+(end-start));
4. gc 垃圾清理机制
二十一.1 BigInteger类
BigInteger适合保存比较大的整型
1.用字符串创建BigInteger:
BigInteger bigInteger1 = new BigInteger("12412412111111111111111111111111111111");
2.BigInteger 不能直接进行+,-,*,/
用add进行加法:
BigInteger add = bigInteger1.add(bigInteger2);
用subtract进行减法:
BigInteger subtract = bigInteger1.subtract(bigInteger2);
用multiply进行乘法
BigInteger multiply = bigInteger1.multiply(bigInteger2);
用divide进行除法
BigInteger divide = bigInteger1.divide(bigInteger2);
二十一.2 BigDecimal类
BigDecimal适合保存精度更高的浮点型
1.用字符串创建BigDecimal:
BigDecimal bigDecimal1 = new BigDecimal("1.200");
BigDecimal bigDecimal2 = new BigDecimal("3.6");
2.BigDecimal 不能直接进行+,-,*,/
用add进行加法:
System.out.println(bigDecimal1.add(bigDecimal2));
用subtract进行减法:
System.out.println(bigDecimal1.subtract(bigDecimal2));
用multiply进行乘法
System.out.println(bigDecimal1.multiply(bigDecimal2));
用divide进行除法,若结果为无限小数,则会报错,此时应该用BigDecimal.ROUND_CEILING 添加参数,保留到分子的小数位
//除法,若为无限小数,则会报错
//System.out.println(bigDecimal1.divide(bigDecimal2));
//除法,此处应该用BigDecimal.ROUND_CEILING添加参数,保留分子的小数位
System.out.println(bigDecimal1.divide(bigDecimal2,BigDecimal.ROUND_CEILING));
完整代码:
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* @author ZHR
* @version 1.0
**/
public class BigNum {
public static void main(String[] args) {
//用字符串创建BigInteger
BigInteger bigInteger1 = new BigInteger("12412412111111111111111111111111111111");
System.out.println(bigInteger1);
//在BigInteger中不能直接进行+,-,*,/
BigInteger bigInteger2 = new BigInteger("123");
//用add进行加法
BigInteger add = bigInteger1.add(bigInteger2);
System.out.println(add);
//用subtract进行减法
BigInteger subtract = bigInteger1.subtract(bigInteger2);
System.out.println(subtract);
//用multiply进行乘法
BigInteger multiply = bigInteger1.multiply(bigInteger2);
System.out.println(multiply);
//用divide进行除法
BigInteger divide = bigInteger1.divide(bigInteger2);
System.out.println(divide);
//创建BigDecimal
BigDecimal bigDecimal1 = new BigDecimal("1.200");
BigDecimal bigDecimal2 = new BigDecimal("3.6");
//加法
System.out.println(bigDecimal1.add(bigDecimal2));
//减法
System.out.println(bigDecimal1.subtract(bigDecimal2));
//乘法
System.out.println(bigDecimal1.multiply(bigDecimal2));
//除法,若为无限小数,则会报错
//System.out.println(bigDecimal1.divide(bigDecimal2));
//除法,此处应该用BigDecimal.ROUND_CEILING添加参数,保留分子的小数位
System.out.println(bigDecimal1.divide(bigDecimal2,BigDecimal.ROUND_CEILING));
}
}
二十二.1 日期类—Date类
(1).创建对象
第一种构造器
Date date1 = new Date();
需要注意:
1.获取当前系统的时间
2.该Data是在java.util包中
3.默认输出的日期格式是国外的,因此需要进行格式的转换
第二种构造器 Date date = new Date(long l),此处的l是距离1970-1-1的毫秒数
Date date2 = new Date(10000);
System.out.println(date2);
(2)格式转换
创建SimpleDateFormat对象,对格式进行规范,这里格式是规范好的
即 yyyy年MM月dd日 hh:mm:ss E 第一个年月日 第二个时分秒 第三个周几 可以调换位置
通过simpleDateFormat.format(date1)进行格式化,返回的是String类型
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
String format = simpleDateFormat.format(date1);
System.out.println(format);
(3)String->Date
可以把格式化的字符串转换成Date
String格式需要与SimpleDateFormat对象的格式一样,否则会抛出异常,因此这里还需要抛出一个异常——throws ParseException
String s = "2021年12月09日 02:28:00 星期四";
Date date3 = simpleDateFormat.parse(s);
System.out.println(date3);
总体的代码:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author ZHR
* @version 1.0
**/
public class Date1 {
public static void main(String[] args) throws ParseException {
// 1.获取当前系统的时间
// 2.该Data是在Java.util包中
// 3.默认输出的日期格式是国外的,因此需要进行格式的转换
Date date1 = new Date();
System.out.println(date1);
// 创建SimpleDateFormat对象,对格式进行规范,这里格式是规范好的
// 即 yyyy年MM月dd日 hh:mm:ss E 第一个年月日 第二个时分秒 第三个周几 可以调换位置
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
String format = simpleDateFormat.format(date1);
System.out.println(format);
//第二种构造器 Date date = new Date(long l),此处的l是距离1970-1-1的毫秒数
Date date2 = new Date(10000);
System.out.println(date2);
// 可以把格式化的字符串转换成Date
// String格式需要与SimpleDateFormat对象的格式一样,否则会抛出异常
String s = "2021年12月09日 02:28:00 星期四";
Date date3 = simpleDateFormat.parse(s);
System.out.println(date3);
}
}
二十二.2 日期类—Calendar类
1.Calendar是一个抽象类,并且构造器是私有的,通过Calendar.getInstance()获取实例
Calendar c = Calendar.getInstance();
2.获取日历对象的日历字段,通过Calendar.get(属性)获取日历字段
System.out.println("年:"+c.get(c.YEAR));
//这里由于老外用月是从0开始
System.out.println("月:"+(c.get(c.MONTH)+1));
System.out.println("日:"+c.get(c.DAY_OF_MONTH));
System.out.println("时:"+c.get(c.HOUR));
System.out.println("分:"+c.get(c.MINUTE));
System.out.println("秒:"+c.get(c.SECOND));
注意月份需要+1,因为老外月份是从0开始的!
3.Calendar没有提供格式方法,需要程序员自己组合
4.若改为24小时制,只需把Calendar.HOUR换为Calendar.HOUR_OF_DAY
二十二.3 LocalDateTime
public class LocalDateTime_ {
public static void main(String[] args) {
//创建LocalDateTime类对象
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
//LocalDateTime方法
System.out.println(now.getYear());
//返回英文月份
System.out.println(now.getMonth());
//返回数字月份
System.out.println(now.getMonthValue());
System.out.println(now.getDayOfMonth());
//若是只考虑日期或者时间
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
//格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E");
System.out.println(dateTimeFormatter.format(now));
//890天后是什么时间
LocalDateTime next = now.plusDays(890);
System.out.println(dateTimeFormatter.format(next));
//看看3459分钟前是什么时间
System.out.println(dateTimeFormatter.format(now.minusMinutes(3459)));
}
}
注意:
1.创建LocalDateTime对象时不是用new方法创建,而是用LocalDateTime now = LocalDateTime.now();创建,LocalDate和LocalTime同样是这样
2.创建DateTimeFormatter对象时不能用new方法创建,而是用DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(“yyyy年MM月dd日 HH:mm:ss E”);创建
二十三.1 集合
一. 数组不足的地方
1.长度必须指定,一旦指定,不能修改,因此数组扩容都是新建一个数组
2.保存同一类型的数据
3.删除或者增加元素比较麻烦
二. 集合优点
1.可以动态保存任意多个对象
2.提供了一系列操作对象的方法,简化了代码
三.单列集合
四. 双列集合
集合的选择:
二十三.2 Collection
一. Collection接口没有直接实现子类,是通过实现他的子接口Set和List来创建对象
Collection c = new ArrayList();
二. Collection方法
1.add 添加单个元素,add的参数是Object,可以装不同类对象
c.add("jack");
这里有一个自动装箱的过程
c.add(10);
c.add(true);
2.remove 删除指定的对象
用法1:删除指定下标的对象,返回是该删除的对象
c.remove(0);
用法2:删除指定元素
c.remove("jack");
3.contains 查找元素是否存在,返回true或者false
System.out.println(c.contains(true));
4.size 获取元素个数
System.out.println(c.size());
5.isEmpty 判断是否为空
System.out.println(c.isEmpty());
6.clear 清空
c.clear();
7.addAll 添加多个元素,形参为集合
ArrayList list = new ArrayList();
list.add("123");
list.add("红楼梦");
c.addAll(list);
System.out.println(c);
8.containsAll 查找多个元素是否存在,形参为集合
System.out.println(c.containsAll(list));
9.removeAll 删除多个元素,形参为集合
c.removeAll(list);
三.遍历元素
1.使用Iterator迭代器
//得到一个集合的迭代器
Iterator iterator = c.iterator();
//iterator.hasNext()判断是否还有元素
//可以使用itit快捷键快速生成
while(iterator.hasNext()){
//iterator.next() 1.获取当前“指针”元素 2.“指针”下移一位
System.out.println(iterator.next());
}
//退出循环后,“指针”指向最后一个元素,如果想要重新遍历,需要重置指针
iterator = c.iterator();
2.使用增强for循环遍历
for (Object o : c){
System.out.println(o);
}
注意:可以使用快捷键 I 直接生成
完整代码:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author ZHR
* @version 1.0
**/
public class CollectionMethod {
public static void main(String[] args) {
//Collection接口没有直接实现子类,是通过实现他的子接口Set和List来创建对象
Collection c = new ArrayList();
//add添加单个元素,add的参数是Object,可以装不同类对象
c.add("jack");
//这里有一个自动装箱的过程
c.add(10);
c.add(true);
System.out.println(c);
//remove,删除指定的对象
//删除指定下标的对象,返回是该删除的对象
c.remove(0);
//删除指定元素
c.remove(10);
System.out.println(c);
//contains:查找元素是否存在,返回true或者false
System.out.println(c.contains(true));
c.add(10);
c.add(true);
//size,获取元素个数
System.out.println(c.size());
//isEmpty,判断是否为空
System.out.println(c.isEmpty());
//clear,清空
c.clear();
System.out.println(c);
//addAll,添加多个元素,形参为集合
ArrayList list = new ArrayList();
list.add("123");
list.add("红楼梦");
c.addAll(list);
System.out.println(c);
//containsAll,查找多个元素是否存在
System.out.println(c.containsAll(list));
//removeAll,删除多个元素
c.removeAll(list);
System.out.println(c);
c.add("jack");
c.add(1);
c.add('a');
//遍历元素
//1.使用Iterator迭代器
//得到一个集合的迭代器
Iterator iterator = c.iterator();
//iterator.hasNext()判断是否还有元素
//可以使用itit快捷键快速生成
while(iterator.hasNext()){
//iterator.next() 1.获取当前“指针”元素 2.“指针”下移一位
System.out.println(iterator.next());
}
//退出循环后,“指针”指向最后一个元素,如果想要重新遍历,需要重置指针
iterator = c.iterator();
//2. 使用增强for循环遍历,底层仍然是迭代器
//快捷键是一个I
for (Object o : c){
System.out.println(o);
}
}
}
二十三.3 List
一.List中元素是有序的,且可以重复
List list = new ArrayList();
list.add("1");
list.add(2);
list.add(3);
list.add(1);
System.out.println(list);
二.List支持索引,通过get方法获得
System.out.println(list.get(0));
System.out.println(list.get(1));
三.List方法
1.void add(int index,Object o) 在index下标插入元素o,该下标的元素后移
list.add(1,"zhr");
System.out.println(list);
2.boolean addAll(int index , Collection eles) 在index下标插入集合eles
List list1 = new ArrayList();
list1.add("lr");
3.indexOf和lastIndexOf是返回第一次和最后一次出现的位置
4.Object remove(int index)移除该下标的元素,返回值为该元素
list.remove(1);
5.set(int index , Object o) 替换,把下标为index的元素替换为o
list.set(2,"程咬金");
6.subList(int start ,int end) 返回子集合, 左闭右开
List list2 = list.subList(0,2);
System.out.println(list2);
完整代码:
import java.util.ArrayList;
import java.util.List;
/**
* @author ZHR
* @version 1.0
**/
public class ListMethod {
public static void main(String[] args) {
List list = new ArrayList();
list.add("张三丰");
list.add("李逵");
//1.void add(int index,Object o) 在index下标插入元素o,该下标的元素后移
list.add(1,"zhr");
System.out.println(list);
//2.boolean addAll(int index , Collection eles) 在index下标插入集合eles
List list1 = new ArrayList();
list1.add("lr");
list.addAll(1,list1);
System.out.println(list);
//indexOf和lastIndexOf是返回第一次和最后一次出现的位置
//Object remove(int index)移除该下标的元素,返回值为该元素
list.remove(1);
//set(int index , Object o) 替换,把下标为index的元素替换为o
list.set(2,"程咬金");
//subList(int start ,int end) 返回子集合, 左闭右开
List list2 = list.subList(0,2);
System.out.println(list2);
}
}
四.List遍历
共有三种方法:
1.使用迭代器遍历
2.使用增强for循环
3.使用普通for循环
//1.使用迭代器Iterator
Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("=================================");
//2.使用增强for循环
for (Object o : list){
System.out.println(o);
}
System.out.println("=================================");
//3.使用普通for循环
for(int i = 0; i<list.size();i++){
System.out.println(list.get(i));
}
五.List排序
类似于数组的sort方法
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* @author ZHR
* @version 1.0
**/
public class ListSort {
public static void main(String[] args) {
List list = new ArrayList();
list.add(new Book("西游记",100));
list.add(new Book("水浒传",90));
list.add(new Book("美猴王",80));
list.add(new Book("三国",70));
list.sort(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
double d1 = ((Book)o1).getPrice();
double d2 = ((Book)o2).getPrice();
if(d1>d2) return 1;
else if(d1<d2) return -1;
else return 0;
}
});
System.out.println(list);
}
}
class Book{
private String name;
private double price;
public Book(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
二十三.4 ArrayList和Vector
二十三.5 LinkedList
自定义双向链表:
import java.util.LinkedList;
/**
* @author ZHR
* @version 1.0
**/
public class LinkedList_ {
public static void main(String[] args) {
Node jack = new Node("jack");
Node tom = new Node("tom");
Node jeny = new Node("jeny");
//连接三个节点,形成链表
jack.next = tom;
tom.next = jeny;
jeny.pre = tom;
tom.pre = jack;
//双向链表的头节点
Node first = jack;
//双向链表的尾节点
Node last = jeny;
//遍历,从头到尾遍历
while(true){
if(first==null) break;
System.out.println(first);
first = first.next;
}
//遍历,从尾到头遍历
while (true){
if(last==null) break;;
System.out.println(last);
last = last.pre;
}
//插入节点,首先再将头节点指向jack
first = jack;
Node smith = new Node("smith");
smith.next = jeny;
tom.next = smith;
smith.pre =tom;
jeny.pre = smith;
//遍历,从头到尾遍历
while(true){
if(first==null) break;
System.out.println(first);
first = first.next;
}
}
}
class Node{
public Object item;
public Node next;
public Node pre;
public Node(Object o){
this.item = o;
}
@Override
public String toString() {
return "Node name = " + item;
}
}
二十三.6 Set
1.Set接口元素是无序的,没有索引的
2.不能放重复的元素
3.可以存放null,但只能有一个null
4.取出的顺序虽然不是添加的顺序,但是固定的
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* @author ZHR
* @version 1.0
**/
public class SetMethod {
public static void main(String[] args) {
// Set接口元素是无序的,没有索引的
// 不能放重复的元素
// 可以存放null,但只能有一个null
// 取出的顺序虽然不是添加的顺序,但是固定的
Set set = new HashSet();
set.add("jack");
set.add("zhr");
set.add("jeny");
set.add("tom");
//遍历方式一,使用迭代器遍历
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
//遍历方式二,使用增强for循环遍历
for (Object o : set) {
System.out.println(o);
}
System.out.println("==========================");
//执行add方法时,会返回一个boolean值,添加成功返回true,添加失败返回false
set = new HashSet();
set.add("jack");
//同时再添加jack会报错
System.out.println(set.add("jack"));
System.out.println("===========================");
set.add(new String("zhr"));//添加成功
set.add(new String("zhr"));//添加失败
System.out.println(set);
}
}
注意:最后字符串的添加!
二十三.7 HashSet
1.底层机制
table是数组+链表(红黑树)
2.HashSet扩容机制和链表转换为红黑树机制
二十三.8 LinkedHashSet
1.LinkedHashSet是HashSet的子类,底层维护了一个数组+双向链表的结构
2.不允许添加相同的元素
3.但是可以按照插入的顺序取出来元素
练习题:
定义一个Car类,添加到LinkedHashSet中,当name和price一致时,是为同一辆车,不能添加。
import java.util.LinkedHashSet;
import java.util.Objects;
/**
* @author ZHR
* @version 1.0
**/
public class LinkedHashedSetHomework {
public static void main(String[] args) {
LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add(new Car("奔驰",100));
linkedHashSet.add(new Car("奔驰",100));
linkedHashSet.add(new Car("奔驰",100));
linkedHashSet.add(new Car("奔驰",100));
System.out.println(linkedHashSet);
}
}
class Car{
private String name;
private double price;
public Car(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "name='" + name + '\'' +
"price=" + price;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return Double.compare(car.price, price) == 0 && Objects.equals(name, car.name);
}
@Override
public int hashCode() {
return Objects.hash(name, price);
}
}
核心就是重写equals和hashCode方法即可
二十三.9 Map
一.对于Map的理解
1.Map用于保存具有映射关系的数据:Key-Value,Key和Value有一一对应的关系
2.Map中的key和value可以是任何类型的数据,会封装到HashMap$Node中
3.Map中的key不允许重复,当有相同的key,等价于替换
4.Map中的value可以重复
5.Map中key和value都可以为null,但是key为空只能有一个,value为空可以有多个
Entry和HashMap$Node关系:
一对k-v是放在一个HashMap$Node中,但由于Node实现了Entry接口,为了方便,封装成entry对象,然后再加到entrySet集合中。所以,一对一k-v就是一个Entry,是接口多态的用法!
代码:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author ZHR
* @version 1.0
**/
public class Map_ {
public static void main(String[] args) {
//Map用于保存具有映射关系的数据:Key-Value,Key和Value有一一对应的关系
Map map = new HashMap();
//Map中的key和value可以是任何类型的数据,会封装到HashMap$Node中
map.put("no1","zhr");
map.put("no2","lrr");
System.out.println(map);
//Map中的key不允许重复,当有相同的key,等价于替换
map.put("no1","xw");
System.out.println(map);
//Map中的value可以重复
map.put("no3","zhr");
System.out.println(map);
//Map中key和value都可以为null,但是key为空只能有一个,value为空可以有多个
map.put(null,null);
map.put("no4",null);
System.out.println(map);
//常用字符串作为key
//通过get(key)方法找到value
System.out.println(map.get("no1"));
//一对k-v是放在一个HashMap$Node中,但由于Node实现了Entry接口,所以,一对一k-v就是一个Entry,是接口多态的用法!
//Node为了方便,封装成entry对象,然后再加到entrySet集合中
Set set = map.entrySet();
for(Object obj : set){
//向下转型
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey()+"-"+entry.getValue());
}
}
}
二.Map的常用方法
1.put 添加,也可以用该方法修改相同key的value
2.remove 根据键删除映射关系
3.get 根据键获取值
4.size 获取元素个数
5.isEmpty 判断是否为空
6.clear 清空
7.containsKey 查找键是否存在
代码:
import java.util.HashMap;
import java.util.Map;
/**
* @author ZHR
* @version 1.0
**/
public class MapMethod {
public static void main(String[] args) {
//Map常用方法
Map map = new HashMap();
//put 添加
map.put("邓超","孙俪");
map.put("tom","jery");
System.out.println(map);
//remove 根据键删除映射关系
map.remove("邓超");
System.out.println(map);
//get 根据键获取值
System.out.println(map.get("tom"));
//size 获取元素个数
System.out.println(map.size());
//isEmpty 判断是否为空
System.out.println(map.isEmpty());
//clear 清空
map.clear();
System.out.println(map);
//containsKey 查找键是否存在
System.out.println(map.containsKey("邓超"));
}
}
三.Map的遍历
这里有三组共六种方法,每组有迭代器和增强for循环两种
第一组 通过keySet获取key,从而访问value
第二组 把所有的values取出
第三组 通过entrySet访问key和value
需要注意,keySet类型是Set,values是Collection
代码:
import java.util.*;
/**
* @author ZHR
* @version 1.0
**/
public class MapFor {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no1","zhr");
map.put("no2","lr");
map.put("no3","xhj");
map.put("no4","yd");
map.put("no5","xw");
map.put("no6","cxc");
//第一组 通过keySet获取key,从而访问value
Set keyset = map.keySet();
//1.增强for
System.out.println("===============第一种方式=============");
for (Object key : keyset) {
System.out.println(key+"-"+map.get(key));
}
System.out.println("===============第二种方式=============");
//2.迭代器方法
Iterator iterator = keyset.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next+"-"+map.get(next));
}
//第二组 把所有的values取出
Collection values = map.values();
//1.增强for循环
System.out.println("==============第三种方法================");
for (Object value : values) {
System.out.println(value);
}
//2.迭代器
System.out.println("================第四种方法===============");
Iterator iterator1 = values.iterator();
while (iterator1.hasNext()) {
Object value = iterator1.next();
System.out.println(value);
}
//第三组 通过entrySet访问key和value
Set entryset = map.entrySet();
//1.增强for循环
System.out.println("================第五种方法===============");
for (Object obj : entryset) {
//向下转型
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey()+"-"+entry.getValue());
}
//2.使用迭代器访问
System.out.println("================第六种方法===============");
Iterator iterator2 = entryset.iterator();
while (iterator2.hasNext()) {
Map.Entry entry = (Map.Entry) iterator2.next();
System.out.println(entry.getKey()+"-"+entry.getValue());
}
}
}
Map练习:
import java.util.*;
/**
* @author ZHR
* @version 1.0
**/
public class MapHomework {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no1",new Employee01("zhr",17999,"no1"));
map.put("no2",new Employee01("lr",18001,"no2"));
map.put("no3",new Employee01("xw",18002,"no3"));
//方式一
Set key = map.keySet();
for (Object o : key) {
if(((Employee01)map.get(o)).getSal()>18000) System.out.println(o+"-"+map.get(o));
}
//方式二
Collection values = map.values();
for (Object o : values) {
if(((Employee01)o).getSal()>18000) System.out.println(o);
}
//方式三
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
Map.Entry entry = (Map.Entry) next;
if(((Employee01)entry.getValue()).getSal()>18000) System.out.println(entry.getKey()+"-"+entry.getValue());
}
}
}
class Employee01{
private String name;
private double sal;
private String id;
public Employee01(String name, double sal, String id) {
this.name = name;
this.sal = sal;
this.id = id;
}
@Override
public String toString() {
return "Employee01{" +
"name='" + name + '\'' +
", sal=" + sal +
", id='" + id + '\'' +
'}';
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
}
二十三.10 HashMap
一.HashMap小结
1.HashMap是以key-value来存储数据
2.key不能重复,添加相同的key,会替代;value可以重复
3.与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的,底层:数组+链表+红黑树
4.没有实现同步,是线程不安全的
二.底层机制
LinkedHashMap是有序的,添加的顺序等于取出的顺序
二十三.11 Hashtable
一.小结
1.hashtable的使用方法和hashmap基本上一样
2.hashtable的键和值都不能为null
3.hashtable是线程安全的
二.Hashtable底层机制
1.底层有数组:Hashtable$Entry[],初始化大小为11
2.临界值为110.75=8
3.扩容:原数组大小2+1
二十四 Collections工具类
Collections工具类,方法为静态方法
常用方法:
1.reverse(List) 反转List中的元素
2.shuffle(List) 对List中元素进行随机打乱
3.sort(List) 按照自然顺序升序排序
4.sort(List,Comparator) 指定顺序排序
5.swap(List,int i,int j) 将List中下标为i和j的元素进行交换
6.max(Collection) 返回按照自然顺序最大的元素
7.max(Collection,Comparator) 跟据比较器返回最大的元素
8.min 返回按照自然顺序最小的元素
9.min(Collection,Comparator) 跟据比较器返回最小的元素
10.frequency(Collection,Object) 返回指定元素出现的次数
11.copy(List dest,List src) 将src的内容复制到dest中,注意src和dest大小应该一样!
12.replaceAll(List,Object old,Object new) 用新值替换所有旧值
代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.TreeSet;
/**
* @author ZHR
* @version 1.0
**/
public class Collection_ {
public static void main(String[] args) {
//Collections工具类,方法为静态方法
ArrayList arrayList = new ArrayList();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
arrayList.add(4);
arrayList.add(5);
System.out.println(arrayList);
//reverse(List) 反转List中的元素
Collections.reverse(arrayList);
System.out.println(arrayList);
//shuffle(List) 对List中元素进行随机打乱
Collections.shuffle(arrayList);
System.out.println(arrayList);
//sort(List) 按照自然顺序升序排序
Collections.sort(arrayList);
System.out.println(arrayList);
//sort(List,Comparator) 指定顺序排序
Collections.sort(arrayList, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return (Integer)o2-(Integer) o1;
}
});
System.out.println(arrayList);
//swap(List,int i,int j) 将List中下标为i和j的元素进行交换
Collections.swap(arrayList,0,4);
System.out.println(arrayList);
//max(Collection) 返回按照自然顺序最大的元素
System.out.println(Collections.max(arrayList));
//max(Collection,Comparator) 跟据比较器返回最大的元素
ArrayList arrayList1 = new ArrayList();
arrayList1.add("1234");
arrayList1.add("123");
arrayList1.add("12");
arrayList1.add("1");
arrayList1.add("");
System.out.println(Collections.max(arrayList1, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o1).length()-((String)o2).length();
}
}));
//min 返回按照自然顺序最小的元素
System.out.println(Collections.min(arrayList));
//min(Collection,Comparator) 跟据比较器返回最小的元素
//frequency(Collection,Object) 返回指定元素出现的次数
arrayList.add(1);
System.out.println(Collections.frequency(arrayList,1));
//copy(List dest,List src) 将src的内容复制到dest中,注意src和dest大小应该一样!
ArrayList arrayList2 = new ArrayList();
for (int i = 0;i<arrayList.size();i++) arrayList2.add("");
Collections.copy(arrayList2,arrayList);
System.out.println(arrayList2);
//replaceAll(List,Object old,Object new) 用新值替换所有旧值
Collections.replaceAll(arrayList,1,9);
System.out.println(arrayList);
}
}
二十五.1 泛型
一.泛型的优势
1.编译时,检查元素的类型,提高了安全性
2.减少了类型转换的次数,提高了效率
二.泛型的作用:
在类声明的时候,通过一个标识表示类中某个属性的类型,或者某个参数的类型,或者某个函数的返回值
代码演示:
/**
* @author ZHR
* @version 1.0
**/
public class Fanxing01 {
public static void main(String[] args) {
//泛型的好处:
// 1.编译时,检查元素的类型,提高了安全性
// 2.减少了类型转换的次数,提高了效率
//泛型的作用:在类声明的时候,通过一个标识表示类中某个属性的类型,或者某个参数的类型,或者某个函数的返回值
Person<String> person = new Person<>("zhr");
System.out.println(person.f());
}
}
class Person<E>{
E s;
public Person(E s) {
this.s = s;
}
public E f(){
return s;
}
}
使用泛型对hashSet和hashMap赋值
import java.util.*;
/**
* @author ZHR
* @version 1.0
**/
public class Fanxing02 {
public static void main(String[] args) {
//使用泛型对hashset赋值
HashSet<Student> hashSet = new HashSet<>();
hashSet.add(new Student("zhr",21));
hashSet.add(new Student("lr",21));
for (Student student : hashSet) {
System.out.println(student);
}
//使用泛型对hashmap赋值
HashMap<String,Student> hashMap = new HashMap<>();
hashMap.put("zhr",new Student("zhr",21));
hashMap.put("lr",new Student("lr",21));
//使用enreySet中的迭代器遍历
//Map.Entry<String,Student>是enteySet的类型
Set<Map.Entry<String,Student>> entrySet = hashMap.entrySet();
Iterator<Map.Entry<String,Student>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry<String, Student> next = iterator.next();
System.out.println(next.getKey()+"-"+next.getValue());
}
}
}
class Student{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return
"name='" + name + '\'' +
", age=" + age ;
}
}
注意hashMap的entrySet的遍历方式!
三.注意事项
1.给泛型指向数据类型要求是引用类型,而不能是基本数据类型
2.在给泛型指定类型后,可以传入该类型和该类型的子类型
3.泛型的使用形式
ArrayList<Integer> arrayList = new ArrayList<Integer>();
推荐使用简写方法,编译器会进行类型推断
ArrayList<Integer> arrayList = new ArrayList<>();
4.不加<>时,默认泛型是Object类型
二十五.2 自定义泛型类
一.基本语法
class 类名<T,R,…>{
成员
}
二.注意事项
1.属性和方法可以使用泛型,泛型标识符可以有多个
2.使用泛型的数组,不能进行初始化,因为数组不确定占有多大空间
3.泛型类的类型是在创建对象时确定的,因此静态方法不能使用泛型
4.在创建对象时,没有指定类型,默认是Object
二十五.3 自定义泛型接口
一.基本语法
interface 接口名<T,R,…>{
}
二.注意事项
1.接口中,静态成员不能使用泛型,由于接口中属性的类型是public static final修饰,因此属性不能使用泛型
2.泛型接口的类型在继承接口或者实现接口中确定
interface IA extends AA<Double,String>{}
3.没有指定类型,默认为Object
二十五.4 自定义泛型方法
一.基本语法
修饰符 <T,R,…> 返回类型 方法名(参数列表) {…}
二.注意事项
1.可以在普通类中,也可以在泛型类中
2.泛型方法被调用时,类型必须被确定
3.若修饰符后面没有<>,则该方法不是泛型方法,只是使用了泛型
代码:
/**
* @author ZHR
* @version 1.0
**/
public class Fanxing03 {
public static void main(String[] args) {
Car car = new Car();
car.Run("宝马",120);
Fish<String,Integer> fish = new Fish<>();
fish.Swim("小金鱼",10);
}
}
//普通类
class Car{
public <T,R> void Run(T t, R r){
System.out.println(t+"可以最快跑"+r+"km/h");
}
}
//泛型类
class Fish<T,R>{
//是使用了泛型而不是泛型方法
public void Swim(T t, R r){
System.out.println(t+"最快可以游"+r+"km/h");
}
}
二十五.5 泛型的继承和通配符
1.泛型不具备继承性
List<String> list = new ArrayList<>(); //对的
List<Object> list1 = new ArrayList<String>(); //不支持继承
2.<?> 支持任意泛型类型
3.<? extends A> 支持A和A的子类,规定了上限,本来泛型也支持子类,这样写更清楚
4.<? super A> 支持A和A的父类,规定了上限
二十六 JUnit使用
在方法前输入@Test,再使用快捷键alt+enter引入JUnit,即可对方法进行测试。