List、ArrayList、LinkedList
容器 集合
之前学的容器:数组
弊端:只能存指定数据类型---数组长度不可变
List Set Map
List接口
实现类:ArraysList、LinkedList、Vector
ArrayList
容量默认容量为10创建对象时可以自定义
扩容每次扩容1.5倍扩容后容量为15
LinkList 链表 双向链表
ArrayList 和 LinkedList比较
ArrayList:通过数组存储数据 查找数据非常快 插入和删除慢
LinkedList:查找速度慢通 过双向检索优化检索速度 插入和删除快
创建集合
List list=new ArrayList();
ArrayList<String> list2=new ArrayList<>();
添加
list.add(2);
list.add(22);
list.add(null);
list.add("java3");
list.add("java4");
list2.add("java");
list2.add(0,"MySQL");
list2.add("java1");
list2.add("java2");
list2.add("java3");
list2.add("java4");
将另一个集合添加进集合中
list2.addAll ( list );
获取指定元素
Objectobj=list.get(2);
System.out.println(obj);
在指定位置插入指定元素,其他元素后移一位
list.add(0,"MySQL");
添加越界 会报错
list.add(8,0); //下标8 已经越界了
集合中是否包含某个元素返回boolean类型
System.out.println(list2.contains("java1"));//true
booleanbool=list.contains("java");
System.out.println(bool);//true
bool=list.indexOf("java")!=-1;
System.out.println(bool);//true
集合中是否包含另外一个集合的所有元素
ListlistA=newArrayList();
ListlistB=newArrayList();
listA.add(33.33);
listA.add(null);
listA.add(2);
listA.add(22);
listB.add(33.33);
listB.add(null);
listB.add(2);
bool=listA.containsAll(listB);
System.out.println(bool);//true
//从前往后查询元素下标
System.out.println(list2.indexOf("java"));
//从后往前查询元素下标
System.out.println(list2.lastIndexOf("java1"));
//修改
list2.set(0,"HTML");
删除删除找到的第一个元素
- 参数传对象删除这个对象的元素返回boolean类型true
- 参数传下标删除这个下标位置的对象返回被删除的对象的元素
- 删除元素为2的用包装类型Integer修饰
System.out.println("-123413-");
System.out.println(list2.remove(2));// 默认删除下标元素
list2.remove("java4");//true
System.out.println(list.remove((Integer)2));//true
System.out.println(list);//[MySQL,22,null,java3,java4]
清除所有元素
list2.clear();
获取长度
System.out.println(list2.size());// 4
判断是否为空
System.out.println(list2.isEmpty());// false
获取指定下标元素
System.out.println(list2.get(3));// java3
查看集合方法
- for循环遍历输出
- 使用for-each循环遍历输出
- 使用迭代器(Iterator)遍历输出
for(inti=0;i<list2.size();i++){
System.out.println(list2.get(i));
}
for(Stringi:list2){
System.out.println(i);
}
Iterator<String>iterator=list2.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println(list2);//[HTML,java,java2,java3]
内部类 静态内部类 匿名内部类
静态内部类
静态内部类可以使用 static 关键字定义,静态内部类我们不需要创建外部类来访问,
静态内部类无法访问外部类的成员
class OuterClass{
int x = 10;
static class InnerClass{
int y=5;
}
}
public class MyMainClass{
public static void main(String[] args){
OuterClass.InnerClass myInner=new OuterClass.InnerClass();
System.out.println(myInner.y);// 5
}
}
成员内部类
- 成员内部类是定义在外部类中的类,它可以访问外部类的属性和方法,并且可以通过外部类的实例来创建内部类的实例。
- 成员内部类可以用public、protected、private等访问修饰符进行修饰,具有与外部类相同的访问权限。
- 成员内部类可以访问外部类的私有成员,但是外部类不能直接访问成员内部类的私有成员,需要通过成员内部类的实例来访问。
public class Outer{
private int value=100;
public class Inner{
public void print(){
System.out.println(value);
}
}
public void test(){
Inner inner=newInner();
inner.print();
}
}
局部内部类
- 局部内部类是定义在方法内部的内部类,它只在所在的方法内部可见,外部其他方法和类无法访问。与成员内部类不同,局部内部类不能有任何访问修饰符(如public、protected、private),因为它的作用域仅限于方法内部。
- 局部内部类可以访问外部类的所有成员,包括私有成员和方法。在局部内部类中访问外部类成员的方式与成员内部类相同,即通过外部类的对象来访问
public class Outer{
private int value=100;
public void test(){
class Inner{
publi cvoid print(){
System.out.println(value);
}
}
Inner inner = new Inner();
inner.print();
}
}
外部类
可以用public或default(默认的)另外两个private、protected不可用
public class EasyInnerClass{...}
class Test{
public static void method(){
EasyInnerClass.InnerA a a= new EasyInnerClass.InnerA();
}
}
匿名内部类 接口或抽象类
- 匿名内部类是一种没有名字的局部内部类,它通常用于只需要使用一次的场合,可以在创建对象的同时实现该对象的方法。匿名内部类通常使用在接口或抽象类的实现、事件处理等场合。
- 匿名内部类是一种没有名字的局部内部类,它通常用于只需要使用一次的场合,可以在创建对象的同时实现该对象的方法。匿名内部类通常使用在接口或抽象类的实现、事件处理等场合。
- 对象new出来两个对象不是同一个
AbstractClassac=newAbstractClass(){
publicvoidmethod(){}
};
AbstractClassaca=newAbstractClass(){
publicvoidmethod(){}
};
System.out.println(ac.getClass());
System.out.println(ac.getClass()==aca.getClass());// false
}
代码块 成员代码块 静态代码块 执行顺序
执行顺序:
1、父类的静态代码块
2、子类的静态代码块
3、父类的成员代码块
4、父类的构造方法
5、子类的成员代码块
6、子类的构造方法
public class EasyBlock{
public static void main(String[] args){
new EasySon();
}
静态代码块:一个类的静态代码块只会执行一次 加载类对象时执行
static{
System.out.println("父类------静态代码块");
}
成员代码块:每一次new对象时执行 在构造方法前运行
{
System.out.println("父类------成员代码块");
}
EasyBlock(){
System.out.println("父类------构造方法");
}
EasyBlock(int num){
System.out.println("父类------带参数构造方法");
}
}
class EasySon extends EasyBlock{
静态代码块:一个类的静态代码块只会执行一次
加载类对象时执行
static{
System.out.println("子类------静态代码块");
}
成员代码块:每一次new对象时执行 在构造方法前运行
{
System.out.println("子类------成员代码块");
}
EasySon(){
System.out.println("子类------构造方法");
}
EasySon(int num){
System.out.println("子类------带参数构造方法");
}
}
输出结果:
父类------静态代码块
子类------静态代码块
父类------成员代码块
父类------构造方法
子类------成员代码块
子类------构造方法
Set、HashSet、LinkedHashSet、TreeSet
Set集合
List是有序的Set是无序的
有序和无序的区别:取出的顺序和添加的顺序是一样的
LinkedHashSet | LinkedHashSet 是 HashSet 的子类,并且其内部是通过 Linked HashMap |
HashSet (无序,唯一) | :基于 HashMap 实现的,底层采用 HashMap 来保存元素 |
TreeSet(有序,唯一) | 红黑树(自平衡的排序二叉树) |
来实现的。有点类似于我们之前说的 `Linked`HashMap 其内部是基于 HashMap 实现一样,不过还是有一点点区别的,可以按照添加顺序遍历
Set中不可以存储相同的数据
set.add(12); // 存储的是Integer类型
set.add("23");
set.add(23);
可以存储null值
set.add(null);
set.add(null);
删除对象
set.remove(12);
System.out.println(set); //[23,23]
TreeSet
遍历的方式: 先序遍历 中序遍历 后序遍历:访问根节点的顺序
TreeSet遍历方式中序遍历
TreeSet不能存储null值
TreeSet 内部使用二叉树 内部节点是可以比较大小的
同一个TreeSet 对象中存储的内容都应该是可以比较的
默认情况西不能存储不同类型
比较器
Comparator<Student>com=(a,b)->(a.grades>b.grades?1:-1);//前面大返回1,后面大返回-1
Comparator<Student>com1=(a,b)->{
if(a.grades==b.grades){
return0;
}
returna.grades>b.grades?1:-1;
};
TreeSet<Student> ttset=new TreeSet<>(com);
Students tua=new Student(); stua.grades=88;
Students tub=new Student(); stub.grades=96;
Students tuc=new Student(); stuc.grades=100;
Students tud=new Student(); stud.grades=86;
Students tue=new Student(); stue.grades=99;
Students tuf=new Student(); stuf.grades=77;
ttset.add(stua); ttset.add(stub); ttset.add(stuc);
ttset.add(stud); ttset.add(stue); ttset.add(stuf);
System.out.println(ttset); | [com.easy722.Student@682a0b20, com.easy722.Student@3d075dc0, com.easy722.Student@214c265e, com.easy722.Student@448139f0, com.easy722.Student@7cca494b, com.easy722.Student@7ba4f24f] |
for(Student i : ttset){ System.out.println(i.grades); }
| 77 86 88 96 99 100 |
比较器
class Student implements Comparable{
int grades;
@Override
public int compareTo(Object o){
if(oinstanceofStudent){
Student item=(Student) o;
if(this.grades==item.grades){
return0;
}
return this.grades>item.grades?1 : -1;
}else{
// o对象不是student就无法比较这是程序运行时出现的特殊情况
// 异常情况我的方法处理不了这种情况就要抛出一个异常情况
// 告知调用这个方法的代码
thrownew RuntimeException("传入参数不可比较");
}
}
}