集合体系结构
Collection:单列集合

LIst系列集合:添加的元素是有序、可重复、有索引
Set系列集合:添加的元素是无序、不重复、无索引
Collection集合常用方法
  | 方法名                     | 说明                               |
  | :------------------------- | :--------------------------------- |
  | boolean add(E e)           | 添加元素                           |
  | boolean remove(Object o)   | 从集合中移除指定的元素             |
  | boolean removeIf(Object o) | 根据条件进行移除                   |
  | void   clear()             | 清空集合中的元素                   |
  | boolean contains(Object o) | 判断集合中是否存在指定的元素       |
  | boolean isEmpty()          | 判断集合是否为空                   |
  | int   size()               | 集合的长度,也就是集合中元素的个数 | 
 
Collection集合的遍历
迭代器遍历
- 迭代器介绍
- 迭代器,集合的专用遍历方式
- Iterator<E> iterator(): 返回此集合中元素的迭代器,通过集合对象的iterator()方法得到
- Iterator中的常用方法
boolean hasNext(): 判断当前位置是否有元素可以被取出
E next(): 获取当前位置的元素,将迭代器对象移向下一个索引位置
Collection集合的遍历
  public class IteratorDemo1 {
      public static void main(String[] args) {
          //创建集合对象
          Collection<String> c = new ArrayList<>();
  
          //添加元素
          c.add("hello");
          c.add("world");
          c.add("java");
          c.add("javaee");
  
          //Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
          Iterator<String> it = c.iterator();
  
          //用while循环改进元素的判断和获取
          while (it.hasNext()) {
              String s = it.next();
              System.out.println(s);
          }
      }
  } 
- 迭代器中删除的方法
 void remove(): 删除迭代器对象当前指向的元素
  public class IteratorDemo2 {
      public static void main(String[] args) {
          ArrayList<String> list = new ArrayList<>();
          list.add("a");
          list.add("b");
          list.add("b");
          list.add("c");
          list.add("d");
  
          Iterator<String> it = list.iterator();
          while(it.hasNext()){
              String s = it.next();
              if("b".equals(s)){
                  //指向谁,那么此时就删除谁.
                  it.remove();
              }
          }
          System.out.println(list);
      }
  } 
 
增强for
- 介绍
- 它是JDK5之后出现的,其内部原理是一个Iterator迭代器
- 实现Iterable接口的类才可以使用迭代器和增强for
- 简化数组和Collection集合的遍历
- 格式
  	for(集合/数组中元素的数据类型 变量名 :  集合/数组名) {
  		// 已经将当前遍历到的元素封装到变量中了,直接使用变量即可
  	}
  public class MyCollectonDemo1 {
      public static void main(String[] args) {
          ArrayList<String> list =  new ArrayList<>();
          list.add("a");
          list.add("b");
          list.add("c");
          list.add("d");
          list.add("e");
          list.add("f");
  
          //1,数据类型一定是集合或者数组中元素的类型
          //2,str仅仅是一个变量名而已,在循环的过程中,依次表示集合或者数组中的每一个元素
          //3,list就是要遍历的集合或者数组
          for(String str : list){
              System.out.println(str);
          }
      }
  } 
- 细节点注意:
1.报错NoSuchElementException
2.迭代器遍历完毕,指针不会复位
3.循环中只能用一次next方法
4.迭代器遍历时,不能用集合的方法进行增加或者删除
public class A04_CollectionDemo4 {
    public static void main(String[] args) {
      /*
        迭代器的细节注意点:
            1.报错NoSuchElementException
            2.迭代器遍历完毕,指针不会复位
            3.循环中只能用一次next方法
            4.迭代器遍历时,不能用集合的方法进行增加或者删除
            	暂时当做一个结论先行记忆,在今天我们会讲解源码详细的再来分析。
                如果我实在要删除:那么可以用迭代器提供的remove方法进行删除。
                如果我要添加,暂时没有办法。(只是暂时)
       */
        //1.创建集合并添加元素
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        //2.获取迭代器对象
        //迭代器就好比是一个箭头,默认指向集合的0索引处
        Iterator<String> it = coll.iterator();
        //3.利用循环不断的去获取集合中的每一个元素
        while(it.hasNext()){
            //4.next方法的两件事情:获取元素并移动指针
            String str = it.next();
            System.out.println(str);
        }
        //当上面循环结束之后,迭代器的指针已经指向了最后没有元素的位置
        //System.out.println(it.next());//NoSuchElementException
        //迭代器遍历完毕,指针不会复位
        System.out.println(it.hasNext());
        //如果我们要继续第二次遍历集合,只能再次获取一个新的迭代器对象
        Iterator<String> it2 = coll.iterator();
        while(it2.hasNext()){
            String str = it2.next();
            System.out.println(str);
        }
    }
} 
 
lambda表达式
函数式编程
函数式编程是一种思想特点。
面向对象:先找对象,让对象先做事情
函数式编程思想,忽略面向对象的复杂语法,强调做什么,而不是谁去做。
标准格式:
    () -> {
}
 
-- ()对应着方法的形参
-- ->固定格式
-- {}方法体
-- 改写之前
Arrays.sort(arr, new Computer<Integer>() {
    @override
    public int compare(Integer o1, Integer o2) {
        return o1 - o2;
    }
});
-- 改写之后
Arrays.sort(arr, (Interger o1, Integer o2) ->{
            return o1 - o2;
        }
); 
注意点:
-- Lambda表达式可以用来简化匿名内部类的书写
-- Lambda表达式只能简化函数式接口的匿名内部类的写法
-- 函数式接口:
有且仅有一个抽象方法的接口叫做函数式接口,接口上方可以加@FunctionalInterface注解
1.利用匿名内部类的形式去调用下面的方法
调用一个方法的时候,如果方法的形参是一个接口,那么我们要传递这个接口的实现类对象
如果实现类对象要用到一次,就可以用匿名内部类的形式进行书写
method( new Swim() {
    @override
    public void swimming() {
        sout("正在游泳~~~");
    }
)};
2.利用lambda表达式进行改写
method(
        () -> {
                sout("正在游泳~~~");
        }
);
public static void method(Swim s){
    s.swimming();
}
interface Swim{
    public abstract void swimming();
}
 
Lambda表达式的省略写法
lambda的省略规则:
1.参数类型可以省略不写
2.如果只有一个参数,参数类型可以省略,同时()也可以省略
3.如果lambda表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略
Integer[] arr = {2, 3, 1, 5, 6, 7, 8, 4, 9};
Arrays.sort(arr, new Computer<Integer>() {
    @override
    public int compare(Integer o1, Integer o2) {
        return o1 - o2;
    }
});
lambda表达式完整格式
Arrays.sort(arr, (Integer o1, Integer o2) -> {
        return o1 - o2;
    }
);
lambda表达式省略写法
Arrays.sort(arr, (o1, o2) -> o1 - o2);
System.out.println(Arrays.toString(arr)); 
 
Collection中的lambda表达式
public class A07_CollectionDemo7 {
    public static void main(String[] args) {
       /* 
        lambda表达式遍历:
                default void forEach(Consumer<? super T> action):
        */
        1.创建集合并添加元素
        Collection<String> coll = new ArrayList<>();
        coll.add("zhangsan");
        coll.add("lisi");
        coll.add("wangwu");
        2.利用匿名内部类的形式
        forEach底层原理:
        其实也会自己遍历集合,依次得到每一个元素
        把得到的每一个元素,传递给下面的accept方法
        s依次表示集合中的每一个数据
       /* coll.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
        //lambda表达式
        coll.forEach(s -> System.out.println(s));
    }
} 
Collection中三种遍历方式
-- 迭代器:在遍历的过程中需要删除元素,请使用迭代器。
-- 增强for、lambda:
仅仅想遍历,那么使用增强for或lambda表达式。
List集合
- List集合的概述
- 有序集合,这里的有序指的是存取顺序
- 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
- List集合的特点
- 存取有序
- 可以重复
- 有索引
- 方法介绍
  | 方法名                          | 描述                                   |
  | ------------------------------- | -------------------------------------- |
  | void add(int index,E   element) | 在此集合中的指定位置插入指定的元素     |
  | E remove(int   index)           | 删除指定索引处的元素,返回被删除的元素 |
  | E set(int index,E   element)    | 修改指定索引处的元素,返回被修改的元素 |
  | E get(int   index)              | 返回指定索引处的元素                   |
  public class MyListDemo {
      public static void main(String[] args) {
          List<String> list = new ArrayList<>();
          list.add("aaa");
          list.add("bbb");
          list.add("ccc");
          //method1(list);
          //method2(list);
          //method3(list);
          //method4(list);
      }
  
      private static void method4(List<String> list) {
          //        E get(int index)		返回指定索引处的元素
          String s = list.get(0);
          System.out.println(s);
      }
  
      private static void method3(List<String> list) {
          //        E set(int index,E element)	修改指定索引处的元素,返回被修改的元素
          //被替换的那个元素,在集合中就不存在了.
          String result = list.set(0, "qqq");
          System.out.println(result);
          System.out.println(list);
      }
  
      private static void method2(List<String> list) {
          //        E remove(int index)		删除指定索引处的元素,返回被删除的元素
          //在List集合中有两个删除的方法
          //第一个 删除指定的元素,返回值表示当前元素是否删除成功
          //第二个 删除指定索引的元素,返回值表示实际删除的元素
          String s = list.remove(0);
          System.out.println(s);
          System.out.println(list);
      }
  
      private static void method1(List<String> list) {
          //        void add(int index,E element)	在此集合中的指定位置插入指定的元素
          //原来位置上的元素往后挪一个索引.
          list.add(0,"qqq");
          System.out.println(list);
      }
  } 
 
List集合的五种遍历方式
1. 迭代器
2. 列表迭代器
3. 增强for
4. Lambda表达式
5. 普通for循环
创建集合并添加元素
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
1.迭代器
Iterator<String> it = list.iterator();
     while(it.hasNext()){
        String str = it.next();
        System.out.println(str);
    }
2.增强for
下面的变量s,其实就是一个第三方的变量而已。
在循环的过程中,依次表示集合中的每一个元素
for (String s : list) {
       System.out.println(s);
   }
3.Lambda表达式
forEach方法的底层其实就是一个循环遍历,依次得到集合中的每一个元素
并把每一个元素传递给下面的accept方法
accept方法的形参s,依次表示集合中的每一个元素
list.forEach(s->System.out.println(s) );
4.普通for循环
size方法跟get方法还有循环结合的方式,利用索引获取到集合中的每一个元素
for (int i = 0; i < list.size(); i++) {
            //i:依次表示集合中的每一个索引
            String s = list.get(i);
            System.out.println(s);
        }
5.列表迭代器
获取一个列表迭代器的对象,里面的指针默认也是指向0索引的
额外添加了一个方法:在遍历的过程中,可以添加元素
ListIterator<String> it = list.listIterator();
while(it.hasNext()){
    String str = it.next();
    if("bbb".equals(str)){
        //qqq
        it.add("qqq");
    }
}
System.out.println(list); 
细节点注意:
List系列集合中的两个删除的方法
1.直接删除元素
2.通过索引进行删除
//1.创建集合并添加元素
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//2.删除元素
//请问:此时删除的是1这个元素,还是1索引上的元素?
//为什么?
//因为在调用方法的时候,如果方法出现了重载现象
//优先调用,实参跟形参类型一致的那个方法。
//list.remove(1);
//手动装箱,手动把基本数据类型的1,变成Integer类型
Integer i = Integer.valueOf(1);
list.remove(i);
System.out.println(list); 
 
                


















