黑马程序员——Java基础---集合类(上)

来源:互联网 发布:redis php扩展 编辑:程序博客网 时间:2024/06/11 00:54

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

集合类知识目录:

一、集合概述

1、对象数组的概述和使用
2、对象数组的内存(图解)
3、集合的由来及集合的继承体系图

二、conllection接口
1、Collection接口概述
2、Collection中的基本方法
3、Collection中批量操作元素的方法
4、Collection中遍历
5、Collection存储自定义对象并遍历
6、迭代器的原理及源码解析
三、List接口
1、List概述
2、List的特点
3、小结_Collection接口和List接口
4、并发修改异常
5、使用List存储自定义对象并遍历
6、自定义集合类_数组实现
7、自定义集合类_链表实现
8、常见数据结构(图解)
四、List的三个子类知识详解
1、List接口的三个子类
2、ArrayList存储自定义对象并遍历
3、Vector存储自定义对象并遍历
4、LinkedList集合
5、去除ArrayList中重复的元素(练习)
6、用LinkedList模拟栈数据结构的集合并测试(练习)
五、JDK1.5新特性——泛型
1、泛型概述
2、泛型类
3、泛型方法
4、泛型接口
5、泛型通配符
六、JDK5.0新特性——foreach循环
1、增强for循环(forEach循环)概述
2、ArrayList存储自定义对象并遍历增强for版(练习)
七、静态导入的概述和使用
八、可变参数
九、Arrays类
十、集合嵌套之ArrayList嵌套ArrayList

总结

集合类知识详解:

一、集合概述

1、对象数组的概述和使用

 * Student[] stuArray = new Student[120];
 * 1.定义了一个120个长度的Student数组;
 * 2.数组的每个元素存储的是一个:Student对象的引用;
 * 3.此时,没有任何的Student对象产生;
 * 4.由于数组是引用类型的数组,所以每个元素都被初始化为:null 
 * 对象数组的弊端:
 * 1.一旦确定长度后,其长度就不能再更改了;这对我们程序员使用起来非常的不方便;
 * 2.数组定义时需要指定数据类型,那么就只能存储这个类型的数据;
 * 针对数组的弊端:Java为我们程序员提供了一种新的工具:集合
 * 1.集合的作用:就是用来装"对象的引用";
 * 2.这些集合就类似于"仓库",我们程序员使用起来, 就可以将它看做是一个:可以存储无限数量的引用的一个大仓库,我们程序员使用时,只需要往里面增、删、改、查元素,其它的操作我们不需要管。

class Student{String name;int age;char sex;int score;}public class Demo {public static void main(String[] args) {/*Student stu1 = new Student();Student stu2 = new Student();Student stu120 = new Student();*///定义一个3长度的Student数组:Student[] stuArray = new Student[3];Student stu1 = new Student();stu1.name = "刘德华";stu1.age = 20;stu1.sex = '男';stu1.score = 88;Student stu2 = new Student();stu2.name = "张学友";stu2.age = 22;stu2.sex = '男';stu2.score = 99;Student stu3 = new Student();stu3.name = "章子怡";stu3.age = 24;stu3.sex = '女';stu3.score = 100;stuArray[0] = stu1;stuArray[1] = stu2;stuArray[2] = stu3;//想新增一个对象,但数组已满,无法存更多的了。Student stu4 = new Student();stu4.name = "郭富城";stu4.age = 26;stu4.sex = '男';stu4.score = 98;int sum = 0;for(int i = 0;i < stuArray.length ; i++){Student stu = stuArray[i];sum += stu.score;}System.out.println("总分:" + sum);System.out.println("平均分:" + (sum / stuArray.length));}}

2、对象数组的内存(图解)


3、集合的由来及集合的继承体系图

 * 为什么出现集合类?
 * 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类。
 * 数组和集合类同是容器,有何不同?
 * 数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
 * 集合类的特点?
 * 集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。


二、conllection接口

1、Collection接口概述

 * Collection 层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。
 * 一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。

2、Collection中的基本方法

 * 注意:如果大家在方法的形参或返回值类型中看到E字母,可以把它当做:Object
 * boolean add(Object e):将参数e添加到集合
 * boolean remove(Object o):将参数o从集合中移除
 * void clear():清空集合
 * boolean contains(Object o):基于equals()进行判断;
 * boolean isEmpty():判断集合是否为空
 * int size():集合中元素的数量;
 * 学习:Collection(List和Set的顶层接口)
 * 使用:子类:ArrayList

public class Demo {public static void main(String[] args) {//1.定义集合对象Collection col = new ArrayList();//多态:可存储重复元素Collection col2 = new HashSet();//不能存储重复元素;//2.向仓库中添加元素System.out.println(col.add("孙悟空"));System.out.println(col.add("猪八戒"));System.out.println(col.add("沙师弟"));System.out.println(col.add("唐僧"));System.out.println(col.add("唐僧"));System.out.println("---------------------------");System.out.println(col2.add("孙悟空"));System.out.println(col2.add("猪八戒"));System.out.println(col2.add("孙悟空"));System.out.println("集合元素:" + col);//3.移除元素System.out.println("删除元素:唐僧: " + col.remove("唐僧"));System.out.println("删除元素:白骨精:" + col.remove("白骨精"));System.out.println("集合元素:" + col);//4.void clear()//col.clear();//System.out.println("清空集合后:" + col);//5.boolean contains(Object o)System.out.println("是否包含:白骨精:" + col.contains("白骨精"));System.out.println("是否包含:孙悟空:" + col.contains("孙悟空"));//6.boolean isEmpty()//col.clear();System.out.println("集合是否为空:" + col.isEmpty());//7.int size():System.out.println("集合中元素的数量:" + col.size());//存储Student对象,使用数据,一旦定义长度,之后就不能改变;//所以,如果我们使用"集合"存储,我们就不用关心长度的问题;}}

3、Collection中批量操作元素的方法

 * boolean addAll(Collection c):将参数集合,一次性全部添加到当前集合
 * boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作
 * boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,则返回 true
 * boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。 

public class Demo {public static void main(String[] args) {Collection c1 = new ArrayList();c1.add("孙悟空");c1.add("猪八戒");c1.add("唐三藏");Collection c2 = new ArrayList();c2.add("白骨精");c2.add("蜘蛛精");c2.add("狐狸精");//将集合c2中的所有元素,一次性全部添加到c1中/*c1.addAll(c2);System.out.println("c1.size : " + c1.size());//6System.out.println("c2.size : " + c2.size());//3System.out.println("c1 : " + c1);System.out.println("c2 : " + c2);*//*c1.removeAll(c2);System.out.println("c1 : " + c1);System.out.println("c2 : " + c2);*///System.out.println(c1.containsAll(c2));System.out.println(c1.retainAll(c2));System.out.println("c1 : " + c1);System.out.println("c2 : " + c2);}}

4、Collection中遍历

 * 对于Collection类型的集合,有两种基本的遍历方法:
 * 1.Object[] toArray()方法:
 * 2.迭代器:Iterator iterator();
 *  Iterator(接口):
 *  boolean hasNext():  如果仍有元素可以迭代,则返回 true。 
 *  Object next() :返回迭代的下一个元素。 

public class Demo {public static void main(String[] args) {Collection c1 = new ArrayList();c1.add("孙悟空");c1.add("猪八戒");c1.add("唐三藏");//遍历方式一:Object[] objArray = c1.toArray();for(int i = 0;i < objArray.length ; i++){System.out.println(objArray[i]);}System.out.println("---------------------------");//遍历方式二:迭代器Iterator it = c1.iterator();while(it.hasNext()){System.out.println(it.next());}}}

5、Collection存储自定义对象并遍历

public class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}public String toString(){return "Student [姓名:" + name + ", 年龄:" + age + "]";}}public class Demo {public static void main(String[] args) {//1.定义一个集合Collection col = new ArrayList();//2.存储对象col.add(new Student("张三",20));col.add(new Student("李四",22));col.add(new Student("王五",24));col.add(new Student("周六",26));col.add(new Student("赵七",27));//3.遍历//遍历方式一:toArray()Object[] objArray = col.toArray();for(int i = 0 ;i < objArray.length ; i++){System.out.println(objArray[i]);}System.out.println("-------迭代器----------------");//遍历方式二:迭代器Iterator it = col.iterator();while(it.hasNext()){//Object obj = it.next();System.out.println(it.next());}}}

6、迭代器的原理及源码解析

interface Iterator{boolean hasNext();Object next();void remove();}interface Collection{Iterator iterator();}class ArrayList implements Collection{ public Iterator iterator() {        return new Itr(); } private class Itr implements Iterator{public boolean hasNext() {return false;}public Object next() {return null;}public void remove() {}  }}

*注意事项:迭代器在使用的时候,有人为了方便,如下使用就会有问题  System.out.println(((Student)it.next()).getName()+”---”+((Student)it.next()).getAge());

三、List接口

1、List概述

 * List接口概述
 * 有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。
 * 用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
 * 与 set 不同,列表通常允许重复的元素。

2、List的特点

 * |--List(接口):1.可以存储重复的;2.有序的(取出时的顺序同存入时)
 * 特有方法:
 * void add(int index,E element):将element添加到index位置;原index位置上元素依次后移;
 * E remove(int index):移除index位置上的元素
 * E get(int index):获取index位置上的元素
 * E set(int index,E element):将element替换原index位置上的元素;
 * 
 * ListIterator listIterator():获取List的迭代器。ListIterator是Iterator的子接口;
 * 跟Iterator的不同:
 * 1.Iterator:单项的迭代器。只能向下遍历;
 * 2.ListIterator:双向的迭代器,可以向上遍历;注意:在向上遍历前,一定要先向下遍历;
 * |--Set(接口):1.不能存储重复元素;2.无序的;

public class Demo {public static void main(String[] args) {//1.实例化一个集合List list = new ArrayList();list.add("张三");list.add("李四");list.add("王五");Iterator it = list.iterator();while(it.hasNext()){System.out.println(it.next());}//在"李四"之前,插入一个"赵七"list.add(1,"赵七");System.out.println("list :" + list);//移除"赵七"list.remove(1);System.out.println("移除赵七后:" + list);//获取王五System.out.println("获取王五:" + list.get(2));//将王五替换为赵七list.set(2, "赵七");System.out.println("将王五替换为赵七后:" + list);//结合Collection的size()和List的get()方法,可以遍历List类型的集合:for(int i = 0; i < list.size() ; i++){System.out.println(list.get(i));}System.out.println("-----------------------");//获取一个ListIteratorListIterator listIt  = list.listIterator();System.out.println("先向下遍历:");while(listIt.hasNext()){System.out.println(listIt.next());}System.out.println("向上遍历:");while(listIt.hasPrevious()){System.out.println(listIt.previous());}System.out.println("=====================");}}

3、小结_Collection接口和List接口

* Collection(接口)
 * |--List(接口):1.有序的;2.可以存储重复元素;
 * |--Set(接口):1.无序的;2.不可以存储重复元素:
 * 
 * Collection(接口)的
 * --基本方法:
 * boolean add(Object e):将参数e添加到集合
 * boolean remove(Object o):将参数o从集合中移除
 * void clear():清空集合
 * boolean contains(Object o):基于equals()进行判断;
 * boolean isEmpty():判断集合是否为空
 * int size():集合中元素的数量;
 * --批量的方法:
 * boolean addAll(Collection c):将参数集合,一次性全部添加到当前集合
 * boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作
 * boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,则返回 true
 * boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。 
 * --遍历方式:
 * 1.toArray():
 * 2.Iterator():
 * List(接口)的:
 * --新增的方法:
 * void add(int index,E element)
 * E remove(int index)
 * E get(int index)
 * E set(int index,E element)
 * ListIterator listIterator()
 * --遍历的方式:
 * 1.结合使用Collection的size()和List接口的get()方法,使用for循环进行遍历;
 * 2.ListIterator迭代器:可以向下遍历,也可以向上遍历;

4、并发修改异常
 * 1.Iterator:remove()方法不会触发并发修改异常;
 * 2.ListIterator:remove()方法不会触发并发修改异常;
 *                set()方法不会触发并发修改异常;
 *                add()方法不会触发并发修改异常;
 * 3.当使用迭代器遍历元素时,通过List的对象去修改元素内容时,会引发并发修改异常:ConcurrentModificationException
 *   解决:
 *   使用迭代器遍历,如果要修改集合,就要通过迭代器去修改。不要通过List对象修改;

public class Demo {public static void main(String[] args) {List list = new ArrayList();list.add("张三");list.add("李四");list.add("王五");ListIterator listIt = list.listIterator();while(listIt.hasNext()){String str = (String)listIt.next();System.out.println(str);if(str.equals("李四")){//listIt.remove();//OK的listIt.set("赵七");//OK的//listIt.add("赵七");//OK的//list.add("赵七");//并发修改异常:通过List对象去修改的;}}System.out.println("----------------------");Iterator it = list.iterator();while(it.hasNext()){System.out.println(it.next());}}}

5、使用List存储自定义对象并遍历

class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}}public class Demo {public static void main(String[] args) {List list = new ArrayList();list.add(new Student("张三",20));list.add(new Student("李四",22));list.add(new Student("王五",24));list.add(new Student("周六",26));//遍历://1.toArray();//2.Iterator();//3.size()和get()方法://4.ListIterator():for (int i = 0; i < list.size(); i++) {Student stu = (Student)list.get(i);System.out.println(stu.name + "," + stu.age);}}}

6、自定义集合类_数组实现

class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}}class MyArrayList {//内部使用数组存储对象private Object[] objArray = new Object[2];private int index = 0;//当前数组可用的索引public void add(Object obj){objArray[index] = obj;index++;//判断数组是否已被填满if(index == objArray.length){System.out.println("数组已满,扩容......");//数组已满,对数组扩容;定义一个新数组,长度设定为原长度的一倍,将原数组中的所有元素复制到新数组中,然后将引用赋给objArray//1.定义一个新数组Object[] newObjArray = new Object[objArray.length * 2];//2.复制数组System.arraycopy(objArray, 0, newObjArray, 0, objArray.length);//3.将新数组的引用赋给objArrayobjArray = newObjArray;}}public int size(){return index;}public Object get(int index){return objArray[index];}}public class Demo {public static void main(String[] args) {MyArrayList list = new MyArrayList();list.add(new Student("张三",20));list.add(new Student("李四",22));list.add(new Student("王五",24));for(int i = 0;i < 3 ;i ++){list.add(new Student("",20));}System.out.println("集合的长度:" + list.size());//遍历集合for(int i = 0 ;i < list.size() ; i++){Student stu = (Student)list.get(i);System.out.println(stu.name + "," + stu.age);}}}

7、自定义集合类_链表实现

class Box {Object obj;Box next;public Box(Object obj, Box next) {super();this.obj = obj;this.next = next;}}class MyLinkedList {private Box firstBox;private int index;//5public void add(Object obj){Box box = new Box(obj,null);index++;if(this.firstBox == null){//第一次存储firstBox = box;return;}else{//遍历链表,找到最后一个链Box tempBox = this.firstBox;while(tempBox.next != null){tempBox = tempBox.next;}//上述循环结束后,tempBox存储的就是最后一个链tempBox.next = box;}}public int size(){return this.index;}public Object get(int index){//类似于数组的索引,从0开始:index = 2(第三个元素)if(index >= this.index){return null;}int n = 0;Box tempBox = this.firstBox;while(n < index){//0 < 2//1 < 2//2 < 2tempBox = tempBox.next;n++;}return tempBox.obj;}}public class Demo {public static void main(String[] args) {MyLinkedList list = new MyLinkedList();list.add("张三1");list.add("张三2");list.add("张三3");list.add("张三4");list.add("张三5");System.out.println(list.get(2));}}

8、常见数据结构(图解)

 * 栈、队列、数组、链表、树、哈希表

 * 面试前要知道的一个知识点:
 * 常见的数据结构的优缺点




二、List的三个子类知识详解

1、List接口的三个子类

 * |--List(接口):1.有序的;2.可以存储重复值
 * |--ArrayList(类):1.数组实现;2.不是同步的(不保证线程安全),效率高;
 * |--Vector(类):1.数组实现;2.同步的(线程安全的),效率低
 * |--LinkedList(类):1.链表实现;
 * 数组结构:查询快,增、删慢;
 * 链表结构:查询慢,增、删快;
 * |--Set(接口):1.无序的;2.不能存储重复值

2、ArrayList存储自定义对象并遍历

class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}}public class Demo {public static void main(String[] args) {ArrayList list = new ArrayList();list.add(new Student("张三",20));list.add(new Student("李四",22));list.add(new Student("王五",24));list.add(new Student("周六",26));list.add(new Student("周六",26));//遍历:四种://toArray();//Iterator;//get();//ListIterator//使用第三种for(int i = 0;i < list.size() ; i++){Student stu = (Student)list.get(i);System.out.println(stu.name + "," + stu.age);}}}

3、Vector存储自定义对象并遍历

 * Collection:
 * |--List:
 * |--Vector:数组实现;同步的(线程安全的),效率低;
 * 特有方法
 * public void addElement(E obj):添加一个元素;(相当于Collection的add()方法)
 * public E elementAt(int index):获取index位置上的元素;(相当于List的get()方法)

public class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}}public class Demo {public static void main(String[] args) {//1.实例化一个VectorVector vec = new Vector();//2.填充集合vec.add(new Student("刘德华",20));vec.add(new Student("张学友",22));vec.addElement(new Student("章子怡",18));vec.addElement(new Student("汪峰",80));//3.遍历for(int i = 0;i < vec.size() ; i++){Student stu = (Student)vec.elementAt(i);//Student stu = (Student)vec.get(i);System.out.println(stu.name + "," + stu.age);}}}

4、LinkedList集合
 * Collection:
 * |--List:
 * |--LinkedList:链表实现。非同步的(线程不安全的),效率高;
 * 特有功能
 * public void addFirst(E e)及addLast(E e):
 * public E getFirst()及getLast()
 * public E removeFirst()及public E removeLast()

public class Demo {public static void main(String[] args) {LinkedList list = new LinkedList();//list.add("aaa");//list.add("bbb");//list.add("ccc");list.addFirst("aaa");list.addFirst("bbb");list.addFirst("ccc");for(int i = 0;i < list.size() ; i++){//System.out.println(list.get(i));System.out.println(list.getLast());//System.out.println(list.getFirst());//list.removeLast();//i--;}}}

5、去除ArrayList中重复的元素(练习)

public class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}public boolean equals(Object obj){Student stu = (Student)obj;return this.name.equals(stu.name) &&this.age == stu.age;}}public class Demo {public static void main(String[] args) {ArrayList list = new ArrayList();list.add(new Student("李四",22));list.add(new Student("李四",22));list.add(new Student("李四",22));list.add(new Student("张三",20));list.add(new Student("李四",22));list.add(new Student("李四",22));list.add(new Student("王五",24));list.add(new Student("王五",24));list.add(new Student("王五",24));list.add(new Student("王五",24));list.add(new Student("王五",24));//方式一:ArrayList newList = new ArrayList();System.out.println(newList.size());//遍历loop:for(int i = 0;i < list.size() ;i++){Student stu = (Student)list.get(i);for(int j = 0;j < newList.size() ; j++){Student stu2 = (Student)newList.get(j);if(stu.equals(stu2)){continue loop;}}//将stu添加到newList中newList.add(stu);}//遍历newListfor(int i = 0 ;i < newList.size() ; i++){Student stu = (Student)newList.get(i);System.out.println(stu.name + "," + stu.age);}//方式二:/*for(int i = 0; i < list.size() - 1 ; i++){Student stu1 = (Student)list.get(i);for(int j = i + 1 ; j < list.size() ; j++){Student stu2 = (Student)list.get(j);if(stu1.equals(stu2)){list.remove(j);j--;}}}//遍历原集合for(int i = 0; i < list.size() ; i++){Student stu = (Student)list.get(i);System.out.println(stu.name + "," + stu.age);}*/}}

6、用LinkedList模拟栈数据结构的集合并测试(练习)

class MyLinkedList {private LinkedList list = new LinkedList();public void add(Object obj){this.list.addFirst(obj);}public Object get(int index){return this.list.get(index);}public int size(){return this.list.size();}}public class Demo {public static void main(String[] args) {MyLinkedList list = new MyLinkedList();list.add("aaa");list.add("bbb");list.add("ccc");for(int i = 0;i < list.size() ; i++){System.out.println(list.get(i));}}}

三、JDK1.5新特性——泛型

1、泛型概述

* 泛型:
 * 1.当我们定义一个集合后,我们可以向集合中添加什么数据?任何的引用类型;
 * 2.当我们取出时,尤其是需要"向下转型"时,会给我们带来很大麻烦;
 * 3.实际上我们开发时,经常只需要一个集合中只存储一种数据类型的引用;
 * 4.这时,Java为我们提供了一种机制:
 * 1).在定义集合时,就强制定义了这个集合中只能存储哪种类型的数据;
 * 2).如果代码中,试图存储其它类型的数据时,编译时,就会发生错误;
 *   这种机制:泛型
 * 5.示例:
 * //定义一个只存储字符串的集合
 * List<String> strList = new ArrayList<String>();
 * 或:
 * List<String> strList = new ArrayList<>();//(常用)
 * 或:
 * List<String> strList = new ArrayList();
 * //存储元素
 * strList.add("abc");//OK的
 * strList.add(20);//编译错误
 * //遍历取出时--不需要强制转换
 * for(int i = 0;i < strList.size(); i++){
 * String str = strList.get(i);
 * }
 * 6.注意:泛型只存在于"编译期",当生成class文件后,就没有泛型信息了;

public class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}public boolean equals(Object obj){Student stu = (Student)obj;return this.name.equals(stu.name) &&this.age == stu.age;}}public class Demo {public static void main(String[] args) {ArrayList list = new ArrayList();list.add("aaa");list.add(10);//自动装箱list.add(true);//自动装箱list.add(3.14);//自动装箱list.add(new Student("张三",20));ArrayList list2 = new ArrayList();list2.add("aaa");list2.add("bbb");list2.add("ccc");list2.add(new Student("张三",20));/*for(int i = 0;i < list2.size() ; i++){//很多时候,我们为了访问所存储对象的"特有成员",经常要向下强转为所存储的类型String str = (String)list2.get(i);}*///使用泛型定义集合ArrayList<String> strList = new ArrayList<>();strList.add("aaa");//strList.add(20);//编译错误for(int i = 0;i < strList.size() ; i++){String str = strList.get(i);}ArrayList<Student> stuList = new ArrayList<>();stuList.add(new Student("张三",20));for(int i = 0;i < stuList.size() ; i++){Student stu = stuList.get(i);System.out.println(stu.name + "," + stu.age);}}}

2、泛型类

 * 泛型类的定义:
 * 1.在"类名后"使用一对<>括号;
 * 2.里面可以定义泛型名称;
 * 3.泛型名称:
 * 1).可以是一个字母;也可以是多个字母;
 * 2).可以小写,可以大写;
 * 3).可以是一个,可以是多个;多个的话使用逗号分隔;

public class MyLinkedList<abc> {public void add1(abc obj){}}public class Demo {public static void main(String[] args) {MyLinkedList<String> list = new MyLinkedList<>();}}

3、泛型方法

public class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}public boolean equals(Object obj){Student stu = (Student)obj;return this.name.equals(stu.name) &&this.age == stu.age;}}public class MyLinkedList {//接收三个某种类型的数据//能返回一个具有这种类型泛型的一个集合对象;public <T> List<T> add1(T obj1,T obj2,T obj3){List<T> list = new ArrayList<>();list.add(obj1);list.add(obj2);list.add(obj3);return list;}}public class Demo {public static void main(String[] args) {MyLinkedList list = new MyLinkedList();List<String> strList = list.add1("aaa", "bbb", "ccc");List<Student> stuList = list.add1(new Student("a",20), new Student("b",22), new Student("c",24));}}
4、泛型接口

 * 当子类实现了一个带泛型的接口时:
 * 有三种可选择的操作:
 * 1.丢弃泛型;方法内的泛型部分全部变为Object类型;
 * class SubA implements IA{
 * public void add(Object obj){
 * }
 * }
 * 2.指定一个具体类型:
 * class SubA implements IA<String>{
 * public void add(String str){
 * }
 * }
 * 3.继续支持泛型;(子类常见的方式)
 * class SubA<E> implements IA<E>{
 * public void add(E e){
 * }
 * }

public interface IA <E>{public void add(E e);public E get(int index);}public class SubA<E> implements IA<E> {@Overridepublic void add(E e) {// TODO Auto-generated method stub}@Overridepublic E get(int index) {// TODO Auto-generated method stubreturn null;}}public class Demo {ArrayList list;}

5、泛型通配符

 * 泛型通配符
 * 1.<?> : 
 * 1).变量可以指向什么类型的对象:具有任何泛型的集合对象;
 * 2).可以存储什么东西:由于?不确定具体类型,所以不能add()任何类型
 * 3).取出时用什么接收:只能用Object接收;
 * 作用:不能存入,只能获取,所以一般用作方法的返回值声明;
 * 2.<? extends E> :
 * 1).变量可以指向什么类型的对象:具有E泛型或者E子类泛型的集合;
 * 2).可以存储什么东西:由于不确定是哪个E的子类,所以不能存任何东西;
 * 3).取出时用什么接收:只能用E及E的父类类型接收;
 * 3.<? super E> : 
 * 1).变量可以指向什么类型的对象:具有E泛型或者E父类泛型的集合;
 * 2).可以存储什么东西:只能存储E或者E的子类对象;
 * 3).取出时用什么接收:由于存储的可能是任何的E的子类对象,所以只能用Object接收;

class Animal{}class Cat extends Animal{};class Dog extends Animal{};class JMDog extends Dog{};public class Demo {public static void main(String[] args) {//1.<?>List<?> list1 = new ArrayList<>();List<?> list2 = new ArrayList<String>();List<?> list3 = new ArrayList<Animal>();////list2.add("aa");//list2.add(10);//list2.add(new Animal());Object obj = list2.get(0);//2.<? extends E>//List<? extends Dog> list4 = new ArrayList<Animal>();//编译错误List<? extends Dog> list5 = new ArrayList<Dog>();List<? extends Dog> list6 = new ArrayList<JMDog>();/*list5.add("你好");list5.add(10);list5.add(new Animal());list5.add(new Dog());list5.add(new JMDog());*/Dog d1 = list5.get(0);Animal a1 = list5.get(0);//3.<? super E>List<? super Dog> list7 = new ArrayList<Animal>();List<? super Dog> list8 = new ArrayList<Dog>();//List<? super Dog> list9 = new ArrayList<JMDog>();//list7.add(new Animal());list7.add(new Dog());//list7.add(new Cat());list7.add(new JMDog());Object d = list7.get(0);}}

六、JDK5.0新特性——foreach循环

1、增强for循环(forEach循环)概述

 * 1.可以遍历数组,可以遍历集合
 * 2.格式:
 * int[] array = {143,32,5,234,32,4};
 * for(int i = 0;i < array.length ; i++){
 * int n = array[i];
 * System.out.println(n);
 * }
 * //使用增强for
 * for(int n : array){
 * System.out.println(n);
 * }
 * 3.特点:不需要使用"循环变量";
 *  4.当不需要使用循环变量时:只是简单的从头遍历元素到末尾,这时可以选择:增强for语句;
 *    如果遍历时,需要使用循环变量,那么就使用普通for循环;

public class Demo {public static void main(String[] args) {int[] array = {1,432,4325,4324,13,435};for(int n : array){System.out.println(n);}//遍历集合时,被编译成了"迭代器的方式",会可能产生并发修改异常;List<String> strList = new ArrayList<>();strList.add("aaa");strList.add("bbb");strList.add("ccc");for(String s : strList){System.out.println(s);if(s.equals("bbb")){strList.add("ddd");}}}}

2、ArrayList存储自定义对象并遍历增强for版(练习)

public class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}}public class Demo {public static void main(String[] args) {List<Student> stuList = new ArrayList<>();stuList.add(new Student("刘德华",20));stuList.add(new Student("刘亦菲",22));stuList.add(new Student("刘备",24));//使用增强for遍历for(Student stu : stuList){System.out.println(stu.name + "," + stu.age);}}}

七、静态导入的概述和使用

 * 静态导入概述
 * 格式:import static 包名….类名.方法名;
 * 可以直接导入到方法的级别
 * 注意事项
 * 方法必须是静态的
 * 如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。
 * 
 * *当我们需要很频繁的使用到某个类中的某个,或者某些静态方法时, 我们需要通过"类名.方法名()"来访问.
 * *如果频繁调用,可以使用"静态导入",先将方法导入,后使用,使用时不需要使用类名;

import static java.lang.Math.max;//注意:导入的"方法名"import static java.lang.Math.*;//可以使用通配符public class Demo {public static void main(String[] args) {System.out.println(max(10, 20));System.out.println(max(2324, 43392));System.out.println(max(243, 3532));}}
八、 可变参数:
 * 1.在定义方法时,某些形参,如果不确定其数量时,可以指定为:可变参数;
 * 2.格式:数据类型 ... 变量名;
 * 3.在方法内,对于可变参数,是按照"数组"的方式进行处理的;
 * 4.注意:在方法的形参列表内,可以同时指定可变参数和普通参数,可变参数要位于参数列表的末尾;

class MyMath{//求两个整数的和/*public static int sum(int a ,int b){return a + b;}public static int sum(int a , int b,int c){return a + b + c;}*//*public static int sum(int[] array){int sum = 0;for(int n : array){sum+=n;}return sum;}*///可变参数public static int sum(int ...nums ){//可变参数在内部,以数组的方式处理int sum = 0;for(int i = 0;i < nums.length ; i++){sum+=nums[i];}return sum;}}public class Demo {public static void main(String[] args) {System.out.println(MyMath.sum(10, 20));System.out.println(MyMath.sum(10,20,30));int[] array = {1432,32,43,24,314,35};System.out.println(MyMath.sum(array));System.out.println(MyMath.sum(4325,42,432,5,24,321,432,53,62,5,36,5,34,513,432));}}

九、Arrays类

Arrays类的_asList方法_将数组转换为集合

 * Arrays类的asList()方法:将数组转换为集合
 * 获取的集合:不能添加,不能删除;可以修改元素;

public class Demo {public static void main(String[] args) {List<String> strList = Arrays.asList("张三","李四","王五","周六");List<Integer> intList = Arrays.asList(10,2,34,2,5,4,34,2);System.out.println("strList = " + strList.getClass().getName());for(String s : strList){System.out.println(s);}//添加一个元素//strList.add("赵七");//不能添加;运行时异常;//strList.remove(0);//不能删除元素;运行时异常;strList.set(0, "   ");//可以修改元素;System.out.println("集合:" + strList);}}

十、集合嵌套之ArrayList嵌套ArrayList

 * 集合嵌套之ArrayList嵌套ArrayList
 * 
 * 一个班的学员:
 * 刘德华
 * 张学友
 * 郭富城
 * 黎明
 * 另一个班的学员:
 * 章子怡
 * 范冰冰
 * 李宇春
 * 罗玉凤
 * 
 * 将上述两个集合添加到一个大集合中;

public class Demo {public static void main(String[] args) {List<String> class1List = new ArrayList<>();class1List.add("刘德华");class1List.add("张学友");class1List.add("郭富城");class1List.add("黎明");List<String> class2List = new ArrayList<>();class2List.add("章子怡");class2List.add("范冰冰");class2List.add("李宇春");class2List.add("罗玉凤");List<List<String>> list = new ArrayList<>();list.add(class1List);list.add(class2List);for(List<String> classList : list){for(String s : classList){System.out.println(s);}}}}

总结:

集合类的包:java.util.Xxxx

一.类层次结构:

   Collection(接口)

         |--List(接口):1.有序的;2.可以存储重复值;

             |--ArrayList(类):数组实现;

         |--Set(接口):1.无序的;2.不能存储重复值;

二.Collection接口的常用方法:

         1).基本方法:

                   boolean add(Object e):将参数e添加到集合

                   boolean remove(Object o):将参数o从集合中移除

                   void clear():清空集合

                   boolean contains(Object o):基于equals()进行判断;

                   boolean isEmpty():判断集合是否为空

                   int size():集合中元素的数量;

         2).批量方法:

                   boolean addAll(Collection c):将参数集合,一次性全部添加到当前集合

                   boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作

                   boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,则返回 true

                   boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。

         3).遍历的方式:

                   A.toArray();

                   B.Iterator();

三.List接口的常用方法:

         1).新增的方法:

                   void add(int index,E element)

                   E remove(int index)

                   E get(int index)

                   E set(int index,E element)

                   ListIterator listIterator()

         2).遍历的方式:

                   A.结合Collection的size()和List的get()方法,使用for()循环;

                   B.ListIterator:可以向前遍历,也可以向后遍历;

四.Iterator 和 ListIterator的区别:

         1.ListIterator是Iterator的子接口;

         2.Iterator只能向下遍历;

         3.ListIterator可以双向遍历;

 

五.并发修改异常:

         当我们使用迭代器遍历集合时,如果通过集合对象修改集合内的元素,

         这时,会导致并发修改异常;

                   Listlist = new ArrayList();

                   list.add("aaa");

                   list.add("bbb");

                   list.add("ccc");

                   Iteratorit = list.iterator();

                   while(it.hasNext()){

                            Stringstr = (String)it.next();

                            if(str.equals("bbb")){

                                     list.add("ddd");//此处会引发并发修改异常

                            }

                   }

六.数据结构:

         1.栈:先进后出

         2.队列:先进先出

         3.数组:随机获取元素快,增、删慢;

         4.链表:查询慢,增、删非常快;

七:ArrayList:

         1).没有特有方法,都是使用的父接口中定义的;

  Vector类:

  LinkedList类:

八:泛型:

         1.在定义集合时,可以指定这个集合内只能装什么类型元素,这种方式就是“泛型”

                   ArrayList<String>strList = new ArrayList<String>();

                   或:

                   ArrayList<String>strList = new ArrayList<>();

                   或:

                   ArrayList<String>strList = new ArrayList();

         2.泛型类:class MyArrayList<T>{}

                 1.T:可以是任何字母;大小写都可以;

                 2.也可以定义多个泛型,中间用逗号隔开;<T,V>

         3.泛型方法:

                   classMyArrayList{

                            //接收的是什么类型,返回的就是具有这个类型

                            public<T> T show(T t){

                                     returnt;

                            }

                   }

         4.泛型接口:

                   interfaceIA<T>{

                            Tshow(T t);

                   }

           子类实现时:

                   1.可以继续定义泛型:

                            classA <T> implements IA<T>{

                                     publicT show(T t){

                                     }

                            }

                   2.可以固定为某个具体类型

                            classA  implements IA<String>{

                                     publicString show(String s){

                                     }

                            }

                   3.可以将泛型丢弃

                            classA implements IA{

                                     publicObject show(Object o){

                                     }

                            }

         5.泛型的通配符:见Demo

                   1:<?>:

                   2:<?extends E>:

                   3:<?super E>:

九:静态导入:

         1.如果需要很频繁的使用某个类中某些静态方法,可以一次性导入这些静态方法,

         或者导入某个静态方法,导入后,使用这些方法时,不用类名,直接使用即可;

            import static java.lang.Math.abs;

            import static java.lang.Math.*;

十:可变参数:

         1.一个方法如果不确定需要多少个参数,可以定义为:可变参数;

         2.可变参数,跟数组是一样的,所以不能"数组"的方法;

         3.在方法内部,对于可变参数,就是用数组的方式去操作;

         4.在编译后,可变参数的声明,就变成了数组的声明;

         5.调用可变参数的方法:可以不传递实参;

十一:Arrays类的asList()方法;

         1.能够返回具有形参类型的集合对象,内部已经封装了所有的实参;

十二:集合的嵌套:

         1.一个集合内可以嵌套另一个集合;

         2.遍历时要注意,每一层从集合中取出的是什么样的集合;























0 0