集合(全)

1.集合体系结构(分为单列和双列)

单列集合是指添加数据时只能添加一个,双列集合是每次添加一对集合。

2.单列集合(collections)

(1)List系列:添加的元素是有序,可重复,有索引
Set系列:添加的元素是无序,不重复,无索引
(2)常用方法

contain()方法对于自定义对象需要进行重写,底层依赖equals()方法,比较的是地址的值,但是我们需要的是对象属性相等即为contain。

(3)collections遍历

三种遍历方式,不包括for循环(依赖索引),set没有索引不能用for循环。

a.迭代器遍历

用于遍历输出集合元素

Interator<String>it = list.iterator();//用于指向第一个索引位置

细节:

1.报的是没有这个元素异常而不是索引越界,迭代器不依赖索引

2.在迭代器遍历时,不能用list.move()会报错,只能用it.remove();但是没有添加的替换方法。

b.增强for遍历

只有单列集合和数组才能用增强for遍历

for(数据类型 变量名: 集合){sYstem.out.println(变量名);}
c.Lambda表达式遍历()->{}
集合名.forEach(对象名 -> System.out.println(对象名));
追源码其实就是使用了一个for循环,然后使用匿名内部类
集合名.forEach(new Consumer<String>(){
@override
public void accept(String s){
System.out.println(s);
}
});
3.List接口

List实现了collections接口,方法也都实现了。list集合有索引,所以有很多索引操作的方法。

List<String> list = new ArrayList<>();//使用了泛型,List是接口不能直接创建对象
list.add("aaa");list.add("bbb");list.add("ccc");
list.add(0,"qqq");//修改元素
list.remove()//可以根据传入索引删除,还可以直接传入值
//如果方法出现重载现象,就先调用实参和形参类型一致的方法,而不是需要手动装箱再拆箱
list.add(1);//第四个元素,如果我要删除这个元素,不通过索引值,可以通过手动装箱的方式
Integer i = Integer.valueOf(1);
list.remove(i);
//修改元素
String str  = list.set("fff");//返回修改的值,qqq;
//获取元素
String str  = list.set(0);//返回获取的值,fff;
(1)List集合的遍历方式

迭代器遍历、列表迭代器遍历、增强for循环、Lambda表达式遍历、普通for循环遍历

Interator<String>it = list.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}

列表迭代器(add,remove,hasNext,next)

4.数据结构(栈、队列、数组、链表、二叉树、二叉查找树、平衡二叉树、红黑树)

什么时候用哪种集合???怎么结合具体的业务场景来进行选择??

1.每种数据结构长什么样子?2.如何添加数据?3.如何删除数据?

(1)栈(先进后出)

数据进栈称为进栈和压栈,离开栈模型的过程称为弹栈和出栈。

(2)队列(先进先出)
(3)数组

查询快,增删比较慢。

(4)链表

链表中的结点时独立的对象,在内存中是不连续的,每个结点包含数据值和下一个结点的地址。

查询慢,增删比较快。

a.单向链表、双向链表
5.ArrayList源码、Linklist源码、迭代器源码(面试题!后续补)
6.泛型

泛型中只能支持引用数据类型,不能写基本数据类型,只在编译时判断,是否是统一数据类型,在运行时又转为obj类型

(1)泛型类、泛型接口、泛型方法

不知道存什么数据类型(测试类)

MyArrayList<String> list = new MyArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
System.out.println(list);
MyArrayList<String> list1 = new MyArrayList<>();
list1.add(1);
list1.add(3);
list1.add(5);
//System.out.println(list1.get(0))报错会转换成Integer类型
int i = list1.get(0);
System.out.println(i); 
a.泛型类
public class MyArrayList<E>{
Object[] obj = new Object[10];
int size;
public Boolean add(E e){
obj[size] = e;
size++;
return true;
}
public E get(int index){
return (E)obj[index];//返回时要强转,因为在运行时会转成obj类型所以取出的时候要强转
}
public String toString(){
return Arrays.toString(obj);
}
}
b.泛型方法

当方法中形参类型不确定时,可以定义在方法后面

格式:

public <类型>返回值类型 方法名 (类型 变量名)
public <T>void show(T t){} 
public class ListUtil{
    /*
Object[] obj = new Object[10];
int size;
public Boolean add(E e){
obj[size] = e;
size++;
return true;
}
*/
public void  static<T> addAll(ArrayList<T> list,T t2, T t3){
list.add(t2);
list.add(t3);
}
 //添加多个元素
    public void  static<T> addA(ArrayList<T> list,T...t){
        for(T element : list){
            list.add(element);
        }
​
}
public String toString(){
return Arrays.toString(obj);
}
}
//测试类
//泛型的类型在方法被调用时确定下来的
ArrayList<String> list = new ArrayList<>();
ListUtil.addAll(list,"aaa","BBB");
System.out.println(list);//aaa,BBB
ArrayList<Integer> list2 = new ArrayList<>();
ListUtil.addA(list2,1,2,3,4,5,5,6);
System.out.println(list2);
c.泛型接口
import java.util.list;
public class MyArrayList implements list<String>{
//实现所有方法
}
public class MyArrayList1 implements list<E>{
//实现所有方法
}
​
//测试类
MyArrayList list = new MyArrayList();
//只能添加String类型
list.add("qqq");
//实现类不确定类型,可以在创建对象时确定类型
MyArrayList1<String> list1 = new MyArrayList1<>();
​
(2)泛型的通配符和综合类型

泛型没有继承性,但是数据具备继承性

    public void  static<People> addA(ArrayList<People> list){}//只能传入people
    //数据具有继承性
    MyArrayList1<People> list3 = new MyArrayList1<>();
list3.add(new Teacher());
list3.add(new Student());

通配符?用于限制传入数据类型的范围

public void  static<T> addAll(ArrayList<? extends Student,Teacher,String> list){
list.add(t2);
list.add(t3);
}
//测试类main
MyArrayList list = new MyArrayList();
//只能添加String类型
list.add("qqq");
//实现类不确定类型,可以在创建对象时确定类型
MyArrayList1<String> list1 = new MyArrayList1<>();
MyArrayList1<Student> list2 = new MyArrayList1<>();
MyArrayList1<Teacher> list3 = new MyArrayList1<>();
listUtil.addAll(list1);
listUtil.addAll(list2);
listUtil.addAll(list3);
class Student{}
class Teacher{}
7.set系列

(1)HashSet

不重复体现在hashcode和equals方法,一般地通过new一个对象,地址值是不同的,所以哈希值也会不同,引用类型一般重写了两种方法。但是自定义类型需要重写。

a.HashSet的底层原理

package harper1125.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.function.Consumer;
​
/**
 * 特点:无序,不重复,无索引
 */
public class HashSet_ {
    public static void main(String[] args) {
        HashSet<Integer> it = new HashSet<>();
        it.add(3);
        it.add(2);
        it.add(9);
        it.add(8);
        //三种遍历方式
        //迭代器
        Iterator<Integer> its = it.iterator();
        while(its.hasNext()){
            int i = its.next();
            System.out.println(i);
        }
        System.out.println("===========");
        //增强for循环
        for (int j:it) {
            System.out.println(j);
        }
        System.out.println("----------------------");
        System.out.println(it);//[2, 3, 8, 9]
​
    }
​
​
​
}
​
b.三个问题

HashSet根据哈希值计算存入的位置,但是可能哈希值相等的元素,而且jdk8之后是存入的元素挂在老元素后面。索引的话可能几个不同的元素有相同的索引,增加了麻烦,以及HashSet通过equals方法和hashcode比较去重。

(2)LinkedHashSet

(3)TreeSet

最重要的是可排序,以及实现compareTo接口

package harper1125.Set;
import java.util.TreeSet;
/**
 * 不重复,无索引,可排序
 * 可排序是按照从小到大的顺序,参照ASCII表
 * 底层基于红黑树数据结构,增删改查性能好
 *
 */
public class TreeSet_ {
    public static void main(String[] args) {
        TreeSet<Integer> ts = new TreeSet();
        ts.add(2);
        ts.add(1);
        ts.add(-9);
        ts.add(3);
        ts.add(8);
        System.out.println(ts);
        TreeSet<Student> s = new TreeSet();
        s.add(new Student("harper",19));
        s.add(new Student("jack",20));
        s.add(new Student("jill",76));
        s.add(new Student("Alice",5));
        System.out.println(s);
​
​
    }
}
class Student implements Comparable<Student>{
    String name;
    int age;
​
    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 int compareTo(Student o) {
        System.out.println(this);
        int ages = this.age - o.getAge();
        if(ages != 0) return ages;
        return this.name.compareTo(o.getName());
    }
​
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
​
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值