[Java学习日记]Collection与其遍历,ArrayList、LinkedList、Iterator底层

一.Collection常见方法

1.在Java中,Collection接口代表的是什么集合?这种集合有什么特点?
2.在Collection集合中,又分了哪两种集合?
3.这两种集合的特点分别是什么?
4.Collection接口中的的常见方法有哪些(增删查)?
5.在add方法中,List系列与Set系列的返回值有什么不同?
6.remove方法中能使用下标删除吗?
7.contains方法中是使用的什么去比较对象的?
8.对于Set系列,能加入两个属性值相等的对象吗?
public class Demo221 {
    public static void main(String[] args) {
        System.out.println("1.Collection:单列集合,一次只添加一个数据");
        System.out.println("2.单列集合里面又分为Set系列与List系列");
        System.out.println("3.List系列的主要特点就是添加的元素是:有序可重复");
        System.out.println("Set系列的主要特点就是添加的元素是:无序不可重复(类似于Python中的集合Set)");

        System.out.println("4.Collection接口中的的常见方法:增add  删clear remove  查contains isEmpty size");

        Collection<String> collection1 = new ArrayList<>();
        System.out.println("5.对于list系列add方法一定返回true");
        System.out.println(collection1.add("aaa"));
        collection1.add("bbb");
        collection1.add("ccc");
        System.out.println(collection1);


        System.out.println("对于Set系列,如果重复了就返回false");
        Collection<String> collection2 = new HashSet<>();
        System.out.println(collection2.add("aaa"));
        System.out.println(collection2.add("aaa"));
        System.out.println(collection2);

        System.out.println("6.对于共性remove方法,Set无序,只能通过元素对象进行删除,方法有返回");
        collection1.remove("aaa");
        collection2.remove("a");

        System.out.println("7.对于contains方法,右键方法goto选择implementation可以查看其在实现类中的实现");
        System.out.println("底层判断是否相等使用的是equals方法判断,如果自定义对象,想要比较对象值相等,就重写equals吧");
        Collection<Student> collection3 = new ArrayList<>();
        Student s1 = new Student("爱丽丝", 16);
        Student s2 = new Student("爱丽丝", 16);
        collection3.add(s1);
        System.out.println(s2 == s1);
        System.out.println(collection3.contains(s2));

        System.out.println("8.对于Set,只要对象地址不同,都可以加入");
        Collection<Student> collection4 = new HashSet<>();
        collection4.add(s1);
        collection4.add(s2);
        System.out.println(collection4);

        System.out.println("返回是否为空与元素数量,最后删库跑路");
        System.out.println(collection4.isEmpty() + " " + collection4.size());
        collection4.clear();
    }
}

class Student {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        //这里调用的是String的属性的对比
        //如果是数组的话,就调用Arrays工具类去一个一个的比较数组内容,内容相等就返回对
        return age == student.age && Objects.equals(name, student.name);
    }

    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 +
                '}';
    }
}

 


 

二.迭代器遍历Collection元素(可以在有元素要删除的时候用)

1.迭代器依赖索引吗?类名是什么?
2.如何获取迭代器的对象?
3.创建迭代器之后应该如何遍历?
4.如何在迭代器遍历的时候删除元素?
public class Demo222 {
    public static void main(String[] args) {
        System.out.println("1.迭代器不依赖索引,在Java中类是Iterator,是集合专用遍历方式");
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("aaa");
        arrayList.add("bbb");
        arrayList.add("ccc");
        arrayList.add("ddd");
        System.out.println("2.利用集合对象的方法,创建迭代器对象,默认指向0索引");
        Iterator<String> iterator = arrayList.iterator();
        System.out.println("3.判断当前位置是否有元素");
        System.out.println("有元素则输出元素,然后后移,注意:遍历的时候不要用集合的方法增加或者删除元素");
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
        System.out.println();

        //再次获取新的迭代器
        iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            String str = iterator.next();
            if (str.equals("ddd")) {
                System.out.println("4.用迭代器的方法移除迭代器返回的最后一个元素");
                iterator.remove();
            }
        }
        System.out.println(arrayList);
    }
}

 


 

三.增强for循环遍历与lambda表达式遍历

1.增强for遍历集合底层使用的是什么?
2.什么对象能够使用增强for遍历?
3.增强for循环格式?
4.如何使用lambda表达式 + Comsumer 接口遍历集合
public class Demo223 {
    public static void main(String[] args) {
        System.out.println("1.增强for遍历:底层就是迭代器");
        System.out.println("2.所有的单列集合与数组才能用增强for遍历");
        System.out.println("3.for(元素类型 元素名 :数组||单列集合名)");
        int[] arr = {0, 1, 2, 3, 4, 5, 6, 7};
        for (int i : arr) {
            System.out.print(i + " ");
        }
        System.out.println();
        Collection<String> clt = new ArrayList<>();
        clt.add("爱丽丝");
        clt.add("洛琪希");
        for (String s : clt) {
            System.out.print(s+" ");
        }
        System.out.println();

        System.out.println("4.使用集合的forEach方法遍历集合");
        clt.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.print(s+" ");
            }
        });
    }
}

 

 


 

四.List常见方法:增删改查

List集合中,在remove Integer 类型的元素时,优先根据下标删除还是对象的值删除呢?
public class Demo224 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("aaa");
        System.out.println("1.根据下标增");
        arrayList.add(1, "bbb");
        System.out.println(arrayList);
        System.out.println("2.根据下标删");
        arrayList.remove(1);
        System.out.println(arrayList);
        System.out.println("3.根据下标修改,返回被修改的元素");
        System.out.println(arrayList.set(0, "ccc"));
        System.out.println("4.根据下标查");
        System.out.println(arrayList.get(0));

        System.out.println("5.List中默认优先根据下标删除元素");
        System.out.println("当存储的是Integer数据类型时的特殊情况:想要删除特定数字,需要创建Integer对象");
        ArrayList<Integer> arrayList2 = new ArrayList<>();
        arrayList2.add(1);
        arrayList2.add(2);
        arrayList2.remove(Integer.valueOf(1));
        System.out.println(arrayList2);
    }
}

 


 

五.列表迭代器ListIterator:List第5种遍历方式

1.ListIterator与Iterator是什么关系?他有什么更多的用途?
2.ListIterator使用什么方法添加元素?添加元素的位置是怎么决定的?
public class Demo225 {
    public static void main(String[] args) {
        System.out.println("1.ListIterator继承于Iterator,是它的子接口,可以在遍历过程中加元素");
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("aaa");
        arrayList.add("bbb");
        arrayList.add("ccc");
        ListIterator<String> li = arrayList.listIterator();
        System.out.println("2.add()增加元素,增加的位置在当前迭代器指向的位置,默认从0开始, 和remove不一样");
        while (li.hasNext()){
            li.add("嗨嗨嗨");
            String str = li.next();
            //尽量把不为空的写前面
            if ("aaa".equals(str)){
                li.remove();
                li.add("eee");
            }
        }
        System.out.println(arrayList);
    }
}

 


 

六.ArrayList底层原理

1.ArrayList底层为数组
2.空参构造的集合,创建长度默认为0
3.添加第一个元素的时候,扩容为10
4.存满则自动扩容1.5倍(底层是原容量再加原容量右移一位之后的新容量)
5.果扩容之后也超过容量,则按照加入的元素量来扩容(有多少加多少
6.扩容使用arrays.copyOf,创建新的数组然后复制
看源码即可,顺着add方法往下走
public class Demo226 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        System.out.println(arrayList);
    }
}

 


 

七.LinkedList底层与LinkedList特有方法

LinkedList底层与LinkedList特有方法
LinkedList底层是双向链表:
1.源码中私有静态内部类是Node,包括item,prev,next
2.在List类中还有size,first,last代表规模和头尾节点
3.在new一个双向链表的时候,声明了size,first,last,全是空
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
1.在addLast后,先设置一个l保存last
2.new了一个新节点new Node<>(l,e,null)(前一个元素,添加的元素,后一个元素)
3.把last定义为新增加的这个节点
4.如果last节点本来为空(也就是说这个双向链表才刚刚创建),那就把头节点first也设置为新增的元素
否则就设置l(前一个元素)的下一个节点为新增的元素

通过上面的代码我们可以看到,Java中LinkedList如果有至少一个节点
这个双向链表中的头节点和尾节点就都不是指向的空(根本就没有创建这种内部类的对象,只是起一个指向作用)
public class Demo227 {
    public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        System.out.println("LinkedList独有的增删查方法");
        linkedList.addFirst(1);
        linkedList.addLast(2);
        System.out.println(linkedList.getFirst());
        System.out.println(linkedList.getLast());
        linkedList.removeFirst();
        linkedList.removeLast();
        System.out.println(linkedList);
    }
}

 

 


 

八.迭代器底层:以ArrayList为例

在ArrayList里面创建了一个私有的内部类的对象,这个对象,实现了迭代器这个接口
在接口对象里面:定义了一个下标,一个上一次返回的下标,还有一个是集合变化的次数的记录
hasNext():判断当前对象是否有元素,就是判断下标是否到达最大值。
next():在这里面注意,内部类使用外部类的元素使用的ArrayList.this.elementData,这里是为了区分外部类元素与内部类元素
每次next的时候都会看是否有集合的数量变化:如果有变化就会报错。
public class Demo228 {
    public static void main(String[] args) {
        //在代码中使用赋值语句,返回的是被赋值的那个数
        int a = 0;
        System.out.println((a++) + " " + (++a) + " " + (a = 1));

        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("aaa");
        arrayList.add("bbb");
        arrayList.add("ccc");
        //这里使用的是接口名接收的对象,故能够使用这个对象的方法
        //但也只能给你用用实现的方法了,只要是接口,实现类的变量是都用不了的
        Iterator<String> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
    }
}

 


 

九.外界调用私有内部类中的成员方法:两种方式

public class Demo229 {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Inter inter = outer.getInner1();
        inter.show();
        InnerFather innerFather = outer.getInner2();
        innerFather.show();
        //直接使用outer.getInner().show()是不行的
    }
}
class Outer{
    Inner1 getInner1(){
        return new Inner1();
    }
    Inner2 getInner2(){
        return new Inner2();
    }
    private class Inner1 implements Inter{
        @Override
        public void show() {
            System.out.println("私有内部类的方法,外界可以使用接口接收并调用");
        }
    }
    private class Inner2 extends InnerFather{
        @Override
        public void show() {
            System.out.println("私有内部类的方法,外界可以使用父类接收并调用");
        }
    }
}
interface Inter{
    void show();
}
abstract class InnerFather{
    void show() {}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值