文章目录
- 数组
- 字符串String
- StringBuilder
- StringJoiner
- 集合
-
- 单列集合
-
- Collection接口
- List接口
- ArrayList
- LinkedList
- Set接口
- TreeSet
- HashSet
-
- 提高查询性能
- String类型
- 自定义对象类型
-
- 不重写equals方法
- 只重写equals方法
- 只重写hashCode方法
- [重写equals方法和hashCode方法 return 1 去重](#重写equals方法和hashCode方法 return 1 去重)
- LinkedHashSet
- Collections集合工具类
- 双列集合
- 迭代器遍历
- 泛型
- Queue
数组
静态初始化
数据类型 数组名[]= new 数据类型[]{数据值,...};
or
数据类型[] 数组名= new 数据类型[]{数据值,...};
or
数据类型 数组名[]= {数据值,...};
or
数据类型[] 数组名= {数据值,...};
int arr []=new int []{1,2,3};
int arr1 []={1,2,3};
int[] arr2 ={1,2,3};
int [] arr3 ={1,2,3};
int [] arr4 =new int[]{1,2,3};
动态初始化
数据类型 数组名[]= new 数据类型[length];
or
数据类型[] 数组名= new 数据类型[length];
int [] arr5 =new int[5];
int [][] dp =new int[5][5];
声明方式
// 方式1:声明时指定大小
int[] arr1 = new int[5]; // 默认初始化为0
// 方式2:声明并直接赋值
int[] arr2 = {1, 2, 3, 4, 5};
// 方式3:匿名数组
int[] arr3 = new int[]{1, 2, 3};
// 方式4:先声明后初始化
int[] arr4;
arr4 = new int[10];
多维数组
// 二维数组
int[][] matrix = new int[3][4]; // 3行4列
int[][] matrix2 = {{1,2}, {3,4}}; // 直接初始化
// 不规则数组(每行长度不同)
int[][] jagged = new int[3][];
jagged[0] = new int[2];
jagged[1] = new int[5];
jagged[2] = new int[3];
数组核心特性
长度固定 创建后不可改变,length属性获取大小
索引访问 从0开始,到length-1结束
连续内存 元素在内存中连续存储
类型检查 编译时检查类型安全
可存储对象 可存储基本类型或引用类型
遍历
int[] nums = {10, 20, 30, 40, 50};
// 方式1:for循环(可修改元素)
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
// 方式2:增强for循环(只读)
for (int num : nums) {
System.out.println(num);
}
// 方式3:Lambda表达式(Java 8+)
Arrays.stream(nums).forEach(System.out::println);
Arrays工具类
public static void main(String[] args) {
int[] arr = {10,20,30,40,50,60,70,80,90,100};
// Arrays.toString(arr);
int[] arr1 = {10,20,30,40,50,60,70,30,90,100};
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.equals(arr1,arr));
System.out.println(Arrays.binarySearch(arr,10));
Arrays.sort(arr1);
System.out.println(Arrays.toString(arr1));
}
int[] nums = {3, 1, 4, 1, 5};
Arrays.sort(nums);
// 结果:[1, 1, 3, 4, 5](升序,原地修改)
String[] strs = {"banana", "apple", "cherry"};
Arrays.sort(strs); // 按自然顺序(Comparable)
Arrays.sort(nums, fromIndex, toIndex);
// 排序 [fromIndex, toIndex)
// 示例:只排序第1到第4个元素(不含第4个)
Arrays.sort(nums, 1, 4);
//自定义比较器
Integer[] nums = {3, 1, 4, 1, 5};
// 降序排序
Arrays.sort(nums, (a, b) -> b - a);
// 或
Arrays.sort(nums, Collections.reverseOrder());
排序
Arrays.sort(arr); // 快速排序,O(n log n)
查找
(必须先排序)
int index = Arrays.binarySearch(arr, 4); // 返回索引,不存在返回负数
填充
Arrays.fill(arr, 0); // 全部填充为0
复制
int[] copy = Arrays.copyOf(arr, 10); // 复制并扩容
int[] range = Arrays.copyOfRange(arr, 1, 3); // 复制[1,3)范围
比较
boolean equal = Arrays.equals(arr1, arr2);
转字符串
String str = Arrays.toString(arr); // [1, 3, 4, 5, 9]
多维数组转字符串
int[][] matrix = {{1,2}, {3,4}};
String deep = Arrays.deepToString(matrix); // [[1, 2], [3, 4]]
并行排序
(大数据量更快)
数组与集合转换
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
数组 → List
(固定大小,不能增删)
List<String> list = Arrays.asList("a", "b", "c");
数组 → ArrayList
(可变)
List<String> arrayList = new ArrayList<>(Arrays.asList("a", "b"));
List → 数组
String[] arr = list.toArray(new String[0]);
基本类型数组 → List
(需要手动装箱)
int[] nums = {1, 2, 3};
List<Integer> numList = Arrays.stream(nums).boxed().toList();
Arrays.parallelSort(arr);
重点说明
获取数组长度
一维数组获取数组长度
数组名.length
多维数组获取数组长度
int[][] matrix = {
{1, 2, 3},
{4, 5, 6, 7}, // 可以不等长
{8, 9}
};
// 获取行数(外层数组的长度)
int rows = matrix.length; // 3
// 获取特定行的列数(内层数组的长度)
int colsRow0 = matrix[0].length; // 3
字符串String
java.lang.String
字符串不可变
直接赋值、new
package com.yeyu.day1;
public class StringTest {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
str1="sss";
System.out.println(str1);//sss
String str3 = new String("sss1");
System.out.println(str3);
String str4 = new String();
System.out.println(str4);//
char[] chs={'a','b','c'};
String str5 = new String(chs);
System.out.println(str5);//abs
byte[] bytes ={97,98};
String str6 = new String(bytes);
System.out.println(str6);//ab
boolean result1=str1.equals(str2);
System.out.println(result1);//false
System.out.println(str2.charAt(1));//e
System.out.println(str2.length());5
}
}
比较
boolean equals 完全一样
boolean equalsIgnoreCase 忽略大小写
遍历
public char charAt(int index)
public int length()
StringBuilder
可以看作一个容器,创建之后里面的内容是可变的
常用方法
append添加数据
reverse反转
length已经有多少
toString
capacity可以存多少字符
package com.yeyu.day1;
public class StringBuilderTest {
public static void main(String[] args) {
StringBuilder s=new StringBuilder();
StringBuilder s1=new StringBuilder("abc");
System.out.println(s1);//abc
System.out.println(s1.reverse());//cba
System.out.println(s1);//cba
s1.append("abc");
System.out.println(s1);//cbaabc
System.out.println(s1.append(1));//cbaabc1
System.out.println(s1.length());//7
String ss=s1.toString();
System.out.println(ss);//cbaabc1
}
}
StringJoiner
可以看着一个容器
public StringJoiner(间隔符号)
public StringJoiner(间隔符号,开始符号,结束符号)
package com.yeyu.day1;
import java.util.StringJoiner;
public class StringJoinerTest {
public static void main(String[] args) {
StringJoiner sj = new StringJoiner(",","{","}");
sj.add("hello").add("world");
System.out.println(sj);//{hello,world}
System.out.println(sj.toString());//{hello,world}
System.out.println(sj.length());//13
}
}
集合
单列集合
一次添加一个元素,均实现Collection接口
ArrayList、LinkedList
List接口
存取有序
有索引
可以存储重复的
TreeSet、HashSet、LinkedHashSet
Set接口
存取无序
无索引
不可以存储重复的
Collection接口
boolean add、remove、contains、isEmpty
void clear
int size
List接口
add remove set get
迭代器遍历
普通/增强for
foreach
ListIterator
倒序遍历:previous,hasPrevious
ArrayList
基于数组
长度可变,自动扩容
不能存基本数据类型
创建默认长度0
用了add之后默认10
超过了则扩容1.5倍
package com.yeyu.day1;
import java.util.ArrayList;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
System.out.println(list);//[hello, world]
ArrayList<String> list1 = new ArrayList<>();
list1.add("hello");
list1.add("world");
System.out.println(list1);//[hello, world]
System.out.println(list1.size());//2
System.out.println(list1.contains("hello"));//true
System.out.println(list1.equals(list));//true
System.out.println(list.remove("hello"));//true
System.out.println(list);//[world]
System.out.println(list1);//[hello, world]
System.out.println(list1.set(0,"world"));//hello
System.out.println(list1);//[world, world]
}
}
LinkedList
基于双链表
List接口
存取有序
有索引
可以存储重复的
Set接口
存取无序
无索引
不可以存储重复的
TreeSet
基于红黑树结构
Set接口
存取无序
无索引
不可以存储重复的
红黑树
添加时当作红的
根节点是黑的
加入时
1、父红,叔红,
则父黑,叔黑,爷红
爷为当前节点再判断
2、父红,黑叔,当前节点为父右
则父为当前节点并左旋,再判断
3、父红,黑叔,当前节点为父左
父黑,爷红,爷右旋
平衡二叉树
左左,右旋
左右,左右旋
右右,左旋
右左,右左旋
自然排序
public class TreeSetTest {
public static void main(String[] args) {
TreeSet<Student> treeSet = new TreeSet<>();
//自然排序
//使用add,会自动调用compareTo方法
//小的左边,大的右边,一样的不存
treeSet.add(new Student("张二",26));
treeSet.add(new Student("李三",23));
treeSet.add(new Student("王四",24));
treeSet.add(new Student("毛五",25));
System.out.println(treeSet);
//取数据,左中右
}
}
public class Student implements Comparable<Student>{
@Override
public int compareTo(Student o) {
return 1;
//return this.age-o.age;//按年龄排
// 1:正序排列,添加顺序
//0:只有第一个
//-1:倒序排列
}
/*
不重写toString会返回地址值
*/
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + "}";
}
private String name;
private int age;
}
比较器排序
//比较器排序
TreeSet<Student> treeSet1 = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
}
});
HashSet
Set接口
存取无序
无索引
不可以存储重复的
底层是哈希表结构
jdk8之前:数组+链表,jdk7头插法,jdk8尾插法
jdk8之后:数组+链表+红黑树,底层基于HashMap
索引计算:hashCode->原始哈希值->右移16位->哈希扰动->与原始哈希值异或进行二次哈希操作->数组长度减1再与之前结果与
提高查询性能
扩容数组
A、数组达到了有16*0.75(加载因子)
每次扩容原数组两倍大小
B、链表挂载超过8(阈值)个,并且数组长度没有超过64
链表转红黑树
链表挂载超过8(阈值)个,并且数组长度超过64
String类型
HashSet<String> hs = new HashSet<String>();
hs.add("a");
hs.add("c");
hs.add("b");
hs.add("b");
System.out.println(hs.size());//3
System.out.println(hs);//[a, b, c]
自定义对象类型
@Override
public boolean equals(Object obj) {
System.out.println("equals方法执行");
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Student student = (Student) obj;
return age==student.age&& Objects.equals(name,student.name);
//return super.equals(obj);
}
@Override
public int hashCode() {
System.out.println("hashCode方法执行");
return 1;//去查
}
不重写equals方法
public static void main(String[] args) {
HashSet<Student> hashSet = new HashSet<>();
hashSet.add(new Student("张三",26));
hashSet.add(new Student("张二",25));
hashSet.add(new Student("张二",25));
hashSet.add(new Student("李四",25));
System.out.println(hashSet);//[Student{name=张三',age=26}, Student{name=张二',age=25}, Student{name=张二',age=25}, Student{name=李四',age=25}]
}
只重写equals方法
HashSet<Student> hashSet = new HashSet<>();
hashSet.add(new Student("张三",26));
hashSet.add(new Student("张二",25));
hashSet.add(new Student("张二",25));
hashSet.add(new Student("李四",25));
System.out.println(hashSet);//[Student{name=张三',age=26}, Student{name=张二',age=25}, Student{name=张二',age=25}, Student{name=李四',age=25}]
只重写hashCode方法
hashCode方法计算索引位置
return 1 未去重
重写equals方法和hashCode方法 return 1 去重
HashSet<Student> hashSet = new HashSet<>();
hashSet.add(new Student("张三",26));
hashSet.add(new Student("张二",25));
hashSet.add(new Student("张二",25));
hashSet.add(new Student("李四",25));
//重写equals方法和hashCode方法,return 1
// hashCode方法执行
// hashCode方法执行
// equals方法执行
// hashCode方法执行
// equals方法执行
// equals方法执行
// hashCode方法执行
// equals方法执行
// equals方法执行
// [Student{name=张三',age=26}, Student{name=张二',age=25}, Student{name=李四',age=25}]
System.out.println(hashSet);//[Student{name=张三',age=26}, Student{name=张二',age=25}, Student{name=李四',age=25}]
LinkedHashSet
基于哈希表
每个元素额外增加一个双链表机制记录存储顺序
Set接口
存取有序
无索引
不可以存储重复的
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("ss");
linkedHashSet.add("sss");
linkedHashSet.add("sss");
System.out.println(linkedHashSet);
Collections集合工具类
可变参数
本质是数组
格式:
数据类型... nums
or
其他参数, 数据类型... nums
Collections类常用方法
public static <T> boolean addAll(Collection<? super T> c,T... elements)批量添加
public static shuffle(List<?> list)打乱
public static binarySearch(List<T> list,T key)二分法查找元素
public static max(Collection<T> c)默认自然排序的最值
public static min
public static swap(List<?> list,int i,int j)交换元素
自定义对象获取最值需要重写Comparable接口
ArrayList<String> students = new ArrayList<>();
Collections.addAll(students,"a","n","c","b");//[a, n, c, b]
System.out.println(students);
System.out.println(Collections.binarySearch(students,"b"));//-2
Collections.sort(students);
System.out.println(students);//[a, b, c, n]
System.out.println(Collections.binarySearch(students,"b"));//1
Collections.shuffle(students);
System.out.println(students);//[n, c, a, b]
ArrayList<Integer> students1 = new ArrayList<>();
Collections.addAll(students1,1,2,3,4,5);
System.out.println(Collections.max(students1));//5
System.out.println(Collections.min(students1));//1
Collections.sort(students1,Collections.reverseOrder());
System.out.println(students1);//[5, 4, 3, 2, 1]
ArrayList<Integer> students2 = new ArrayList<>();
Collections.addAll(students2,1,2,3,4,5);
Collections.sort(students2,new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(students2);//[5, 4, 3, 2, 1]
双列集合
一次添加两个元素
均有Map接口
Map接口
key不允许重复
value可以重复
Entry表示键值对
关键方法
Map<String,String> map = new HashMap<>();
//添加
map.put("a","b");//返回的是被覆盖的值
map.put("c","d");//返回null
map.put("b","f");
map.put("c","h");//返回d
//HashMap存取顺序不一致
System.out.println(map);//{a=b, b=f, c=h}
//删除
//删除键对应的键值对,返回键对应的值
map.remove("c");
System.out.println(map);//{a=b, b=f}
System.out.println(map.isEmpty());//false
System.out.println(map.size());//2
System.out.println(map.containsKey("a"));//true
System.out.println(map.containsValue("f"));//true
map.clear();
System.out.println(map);//{}
System.out.println(map.isEmpty());//true
三种遍历
键集合
//获取所有键
Set<String> keys = map.keySet();
System.out.println(keys);//[a, b, c]
//遍历键集合,遍历值
for(String key:keys){
System.out.println(map.get(key));//b f h
}
Entry键值对集合
Set<Map.Entry<String,String>> entryset= map.entrySet();
for (Map.Entry<String,String> entry:entryset){
System.out.println(entry.getKey()+":"+entry.getValue());
// a:b
// b:f
// c:h
forEach
map.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String key, String value) {
System.out.println(key+":"+value);
}
});
map.forEach((k,v)->{
System.out.println(k+":"+v);
});
TreeMap
键排序,自定义对象需要实现Comparable接口
红黑树
TreeMap<Person,String> treemap = new TreeMap<>();
HashMap
键唯一,需重写hashCode和equals方法
哈希表
键->哈希值
jdk8开始,链长度超过8且数组长度>=64,自动转为红黑树
HashMap<Person,String> hashmap = new HashMap<>();
LinkedHashMap
键唯一,且保证存取顺序
哈希表+双向链表
LinkedHashMap<Person,String> linkedhashmap = new LinkedHashMap<>();
迭代器遍历
public Iterator<E> iterator()
Iterator<E> name=对象.iterator()
boolean hasNext()
E next()将元素取出,并向后移动下一个
void remove一出迭代器返回的最后一个元素
泛型
jdk5引入
泛型类
泛型方法
package com.yeyu.day3;
public class NiMingNeiBuLeiTest {
public static void main(String[] args) {
// 方法的形参是接口类型,传入接口的实现类对象
// test(new InterImpl());
// test(new Inter() {
// @Override
// public void show() {
// System.out.println("匿名内部类");//匿名内部类
// }
// });
// new 类名(){}:继承这个类
// new 接口名(){}:实现这个接口
test((msg)->{System.out.println(msg);});//Lambda
//():匿名内部类被重新写方法的形参列表
//形参参数类型可以不写
//若只有一个形参,类型和()可以不写
//方法体只有一行{}和;可以不写
//只有一行return,return和;必须省略
}
public static void test(Inter i){
i.show("形参");
}
}
泛型接口
interface Inter1<E>{
// void show();
void show(E msg);
}
class Inter2 implements Inter1<String>{
@Override
public void show(String msg) {}
}
class Inter3<E> implements Inter1<E>{
@Override
public void show(E msg) {}
}
泛型通配符
?:任意类型
? extends E:可以传入E或者E的子类
? super E:可以传入E或者E的父类
Queue
// 插入元素
boolean add(E e) // 队列满时抛出异常
boolean offer(E e) // 队列满时返回false(推荐)
// 移除并返回队首
E remove() // 空队列时抛出异常
E poll() // 空队列时返回null(推荐)
// 仅查看队首(不移除)
E element() // 空队列时抛出异常
E peek() // 空队列时返回null(推荐)
Queue 接口
// 基础接口,定义队列的基本操作
public interface Queue<E> extends Collection<E>
主要实现类
实现类 特点 线程安全 适用场景
LinkedList 双向链表实现 ❌ 否 普通队列操作
ArrayDeque 数组实现的双端队列 ❌ 否 高性能双端队列,优先于Stack
PriorityQueue 优先级堆实现 ❌ 否 需要按优先级排序的场景
ConcurrentLinkedQueue 无锁并发队列 ✅ 是 高并发单生产者-单消费者
LinkedBlockingQueue 可选有界阻塞队列 ✅ 是 生产者-消费者模式
ArrayBlockingQueue 有界阻塞队列 ✅ 是 固定容量缓冲
SynchronousQueue 不存储元素 ✅ 是 直接传递
DelayQueue 延迟获取元素 ✅ 是 延迟任务调度
基础队列-LinkedList实现
import java.util.LinkedList;
import java.util.Queue;
public class QueueDemo {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
入队
queue.offer("任务1");
queue.offer("任务2");
queue.offer("任务3");
出队
while (!queue.isEmpty()) {
System.out.println("处理: " + queue.poll());
}
}
}
双端队列
import java.util.ArrayDeque;
import java.util.Deque;
public class DequeDemo {
public static void main(String[] args) {
Deque<Integer> deque = new ArrayDeque<>();
两端操作
deque.addFirst(1); // 队首添加
deque.addLast(2); // 队尾添加
deque.removeFirst(); // 移除队首
deque.removeLast(); // 移除队尾
}
}