个人博客:www.hellocode.top
⭐所有文章均在上方博客首发,其他平台同步更新
本文专栏:Java零基础指南
更多相关内容请点击前往 Java零基础指南 查看
⚡如有问题,欢迎指正,一起学习~~
集合只能存储引用数据类型。如果要存储基本数据类型,需要存储对应的包装类
单列结构
双列结构
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
boolean removeif(Object o) | 根据条件进行删除 |
void clear() | 清空集合 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
Iterator:迭代器,集合的专用遍历方式
Iterator iterator():返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引
Iterator中的常用方法
boolean hasNext()
:判断当前位置是否有元素可以被取出E next()
:获取当前位置的元素,并将迭代器对象移向下一个索引位置步骤:
Iterator it = list.iterator();
迭代器原理
增强for:简化数组和Collection集合的遍历
格式
for(元素数据类型 变量名 : 数组或者Collection集合){
// 在此处使用变量即可,该变量就是元素
}
// 数据类型一定是集合或者数组元素的类型
// 变量名在循环的过程中,依次表示集合或者数组中的每一个元素
注意点:在增强for中,修改第三方变量的值不会影响到集合中的元素
三种循环的使用场景
// 需求:创建一个Collection集合存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
// ----------Student类--------------------
public class Student{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
// ----------Test类--------------------
import java.util.ArrayList;
import java.util.Iterator;
public class test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 16);
Student s3 = new Student("王五", 31);
list.add(s1);
list.add(s2);
list.add(s3);
// 迭代器遍历
Iterator<Student> it = list.iterator();
while (it.hasNext()) {
Student s = it.next();
System.out.println(s);
}
System.out.println("----------------------");
// 增强for遍历
for (Student s : list) {
System.out.println(s);
}
}
}
方法名 | 说明 |
---|---|
void add(int index, E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index, E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
数据结构是计算机存储、组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率
数组是一个查询快、增删慢的模型
链表是一个查询慢、增删快的模型(对比数组)
ArrayList:底层数据结构是数组,查询快、增删慢
LinkedList:底层数据结构是链表,查询慢、增删快
方法名 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
泛型:是JDK5中的特性,它提供了编译时类型安全检测机制
泛型的好处
使用泛型时,只能是引用数据类型
如果一个类后面有
,表示这个类是一个泛型类
在创建泛型类对象时,必须要给这个泛型确定具体的数据类型
泛型的定义格式
<类型>
:指定一种类型的格式尖括号里面可以任意书写,按照变量的定义规则即可。一般只写一个字母。
比如:
、 、 、
修饰符 class 类名<类型>{ }
public class MyGenericityClass<E> {
private E element;
public E getElement() {
return element;
}
public void setElement(E element) {
this.element = element;
}
@Override
public String toString() {
return "MyGenericityClass [element=" + element + "]";
}
}
定义格式:修饰符 <类型> 返回值类型 方法名(类型 变量名){ }
范例:public
// 定义一个泛型方法,传递一个集合和四个元素,将元素添加到集合中并返回
public class GenericityMethod {
public static void main(String[] args) {
addElement(new ArrayList<String>, "a", "b", "c", "d");
}
public static <T> ArrayList<T> addElement(ArrayList<T> list, T t1, T t2, T t3, T t4) {
list.add(t1);
list.add(t2);
list.add(t3);
list.add(t4);
return list;
}
}
使用方式
泛型接口的定义格式:修饰符 interface 接口名<类型>{ }
public class GenericityInterface {
public static void main(String[] args) {
GenericityImpl<String> genericity = new GenericityImpl<>();
genericity.method("ccccccc");
}
}
interface Genericity<E> {
public abstract void method(E e);
}
class GenericityImpl<E> implements Genericity<E> {
public void method(E e) {
System.out.println(e);
}
}
类型通配符:>
ArrayList>:表示元素类型未知的ArrayList,它的元素可以匹配任何的类型
但是并不能把元素添加到ArrayList中了,获取出来的也是父类类型
类型通配符上限: extends 类型>
比如:
ArrayList extends Number>
:它表示的类型是Number或者其子类型
类型通配符下限: super 类型>
比如:
ArrayList super Number>
:他表示传进来的类型可以是Number类型,也可以是Number的父类类型
import java.util.ArrayList;
public class tongpeifu {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
list1.add(11);
list2.add("ssacs");
printList(list1);
printList(list2);
}
private static void printList(ArrayList<?> list) {
// TODO Auto-generated method stub
System.out.println(list);
}
}
Set集合概述和特点
Set集合练习
public class MySet {
public static void main(String args[]) {
Set<String> set = new TreeSet<>();
set.add("ccc");
set.add("aaa");
set.add("aaa");
set.add("bbb");
// 迭代器遍历
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
System.out.println("---------------------------");
// 增强for遍历
for (String s : set) {
System.out.println(s);
}
}
}
特点
自然排序Comparable的使用
重写里面的compareTo方法
@Override
public int compareTo(Student o){
int result = this.age - o.age;
return result;
}
原理
比较器排序Comparator的使用
@Override
public int compare(Teacher o1,Teacher o2){
// o1表示现在要存入的那个元素
// o2表示已经存入到集合中的元素
// 主要条件
int result=o1.getAge()-o2.getAge();
// 次要条件
result=result==0?o1.getName().compareTo(o2.getName()):result;
return result;
}
两种比较方式小结
在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,使用比较排序
二叉树
红黑规则
添加节点
练习:创建3个学生对象,属性为姓名,语数英成绩,按照总分从小到大顺序打印到控制台
// Student类
public class Student implements Comparable<Student> {
private String name;
private int chinese;
private int english;
private int math;
public Student(String name, int chinese, int english, int math) {
super();
this.name = name;
this.chinese = chinese;
this.english = english;
this.math = math;
}
public Student() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getSum() {
int res;
res = chinese + math + english;
return res;
}
@Override
public String toString() {
return "Student [name=" + name + ", chinese=" + chinese + ", english=" + english + ", math=" + math + "]" + "总分为:" + getSum();
}
@Override
public int compareTo(Student o) {
// TODO Auto-generated method stub
int res = this.getSum() - o.getSum();
res = res == 0 ? this.getChinese() - o.getChinese() : res;
res = res == 0 ? this.getMath() - o.getMath() : res;
res = res == 0 ? this.getName().compareTo(o.getName()) : res;
return res;
}
}
// 测试类
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<Student> stu = new TreeSet<>();
Student s1 = new Student("李四", 80, 80, 80);
Student s2 = new Student("张三", 80, 80, 80);
Student s3 = new Student("王五", 80, 80, 80);
stu.add(s1);
stu.add(s2);
stu.add(s3);
for (Student student : stu) {
System.out.println(student);
}
}
}
HashSet集合特点
基本使用
import java.util.HashSet;
import java.util.Iterator;
//import java.util.TreeSet;
public class Hash {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<String> hs = new HashSet<>();
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("java");
hs.add("java");
hs.add("java");
Iterator<String> it = hs.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
}
}
哈希值(哈希码值):是JDK根据对象的地址或者属性值,算出来的int类型的整数
public int hashCode()
)对象的哈希值特点
Map集合概述和使用
创建Map集合的对象
import java.util.HashMap;
import java.util.Map;
public class Base {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String, String> stu = new HashMap<>();
stu.put("2020033001", "张三");
stu.put("2020033002", "李四");
stu.put("2020033003", "王五");
System.out.println(stu);
}
}
Map集合的基本功能
方法名 | 说明 |
---|---|
V put(K key, V value) | 添加元素 |
V remove(Object key) | 根据键删除值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
put方法中,如果要添加的键不存在,则会把键值对都添加到集合中;如果键存在,则会把原先的值覆盖,并当作返回值返回
遍历Map集合
方法名 | 说明 |
---|---|
Set keySet() | 获取所有键的集合 |
V get(Object key) | 根据键获取值 |
Set |
获取所有键值对对象的集合 |
K getKey() | 获得键 |
V getValue() | 获得值 |
案例
需求:创建一个HashMap集合,键是学生对象(Student),值是籍贯(String)。存储三个键值对元素,并遍历
// Student类
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
// 实现类
import java.util.HashMap;
import java.util.Set;
import java.util.Map;
public class HashDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<Student, String> hm = new HashMap<>();
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 22);
Student s3 = new Student("王五", 22);
hm.put(s1, "江苏");
hm.put(s2, "西安");
hm.put(s3, "北京");
// 遍历方式一:获取所有的键,再找对应的值
Set<Student> keys = hm.keySet();
for (Student key : keys) {
String value = hm.get(key);
System.out.println(key + "------" + value);
}
System.out.println("====================");
// 遍历方式二:先获取到所有的键值对对象,再获取到里面的每一个键和值
Set<Map.Entry<Student, String>> entries = hm.entrySet();
for (Map.Entry<Student, String> entry : entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "------" + value);
}
System.out.println("====================");
// 遍历方式三:
hm.forEach(
(Student key, String value) -> {
System.out.println(key + "-----" + value);
}
);
}
}
练习:创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String),学生属性姓名和年龄,按照年龄进行排序并遍历
// Student类
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Student o) {
// 按照年龄进行排序
int result = this.getAge() - o.getAge();
// 次要条件,按照姓名排序
result = result == 0 ? this.getName().compareTo(o.getName()) : result;
return result;
}
}
// 实现类
import java.util.TreeMap;
public class TreeMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeMap<Student, String> tm = new TreeMap<>();
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 22);
Student s3 = new Student("王五", 22);
tm.put(s1, "江苏");
tm.put(s2, "北京");
tm.put(s3, "天津");
tm.forEach(
(Student key, String value) -> {
System.out.println(key + "----" + value);
}
);
}
}
// 需求:定义一个方法求N个数的和
// 在JDK5之前,会把所有的数据都先放到一个数组中,自定义方法形参只要写一个数组就可以了
public static void main(String[] args){
int[] arr = {1, 2, 3, 4, 5};
int sum1 = getSum(arr);
System.out.println(sum1);
}
public static int getSum(int[] arr){
int sum = 0;
for(int i = 0; i < arr.length; i++){
sum += arr[i];
}
return sum;
}
可变参数:就是形参的个数是可以变化的
格式:修饰符 返回值类型 方法名(数据类型...变量名){ }
注意事项
public static void main(String[]args){
int sum=getSum(1,2,3,4,5,6,7);
System.out.println(sum);
}
public static int getSum(int...arr){
int sum=0;
for(int i=0;i<arr.length;i++){
sum+=arr[i];
}
return sum;
}
创建不可变集合
这个集合不能添加、删除、修改
方法名 | 说明 |
---|---|
static List of(E…elements) | 创建一个具有指定元素的List集合对象 |
static Set of(E…elements) | 创建一个具有指定元素的Set集合对象 |
static |
创建一个具有指定元素的Map集合对象 |
应用场景
集合元素的批量添加:
ArrayList
list = new ArrayList<>(List.of("a", "b", "c", "d"));
获取Stream流
创建一条流水线,并把数据放到流水线上准备进行操作
中间方法
流水线上的操作
一次操作完毕之后,还可以继续进行其他操作
终结方法
一个Stream流只能有一个终结方法
是流水线上的最后一个方法
单列集合
可以使用Collection接口中的默认方法stream()生成流:
集合对象.stream();
default Stream
stream()
双列集合
间接的生成流
可以先通过keySet或者entrySet获取一个Set集合,再获取Stream流:集合对象.keySet().stream();
集合对象.entrySet().stream();
数组
Arrays中的静态方法stream生成流:
Arrays.stream(数组名);
同种数据类型的多个数据
1, 2, 3, 4, 5, 6…
“aaa”, “bbb”, “ccc”, …
使用Stream.of(T…values)生成流
在Stream流中无法直接修改集合,数组等数据源中的数据
package Stream;
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo{
public static void main(String[] args){
ArrayList<String> manList = new ArrayList<>();
manList.add("张三");
manList.add("李四");
manList.add("王五");
manList.add("马六");
manList.add("赵七");
manList.add("刘八");
ArrayList<String> womanList = new ArrayList<>();
womanList.add("吴九");
womanList.add("乐十");
womanList.add("杨十一");
womanList.add("廖牛马");
womanList.add("汶十二");
womanList.add("苏十三");
Stream<String> stream1 = manList.stream().filter(name -> name.length() == 3).limit(2);
Stream<String> stream2 = womanList.stream().filter(name -> name.startsWith("杨")).skip(1);
Stream.concat(stream1, stream2).forEach(name -> System.out.println(name));;
}
}
推荐阅读:【Java】IO流详解