7月20号知识点
今天主要内容
-
集合的由来
-
Collection集合的基本功能测试
-
集合的两种基本遍历方式
-
forEach
-
iterator
-
-
List集合的特有功能概述和测试
-
Vector
- Vector与ArrayList的区别于联系
-
List的三个子类的区别
- ArrayList
- LinkedList
- Vector
一、集合框架(集合的由来及集合继承体系图)
-
集合的由来
- 数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少
-
数组和集合的区别
-
区别1 :
-
数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值
-
集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象
-
-
区别2:
-
数组长度是固定的,不能自动增长
-
集合的长度的是可变的,可以根据元素的增加而增长
-
-
-
数组和集合什么时候用
-
如果元素个数是固定的推荐用数组
-
如果元素个数不是固定的推荐用集合
-
-
集合继承体系图
二、集合框架(Collection集合的基本功能测试)
-
boolean add(E e)
-
boolean addAll(Collection<? extends E> c)
-
boolean contains(Object o)
- 调用equals()方法
-
boolean isEmpty()
-
int size()
三、集合框架(集合的遍历之forEach()遍历)
-
forEach是Iterable中的一方法
-
default void forEach(Consumer<? super T> action)
The default implementation behaves as if: for (T t : this) action.accept(t);
-
此时注意forEach的参数为Consumer类型,Consumer是一个接口,只有accept(T t)一个方法,可用lambda返回一个Consumer类型的引用
- void accept(T t) Performs this operation on the given argument.
-
-
forEach例子一:String类型的使用
public class TestArrayList { public static void main(String[] args) { ArrayList<String> arrl = new ArrayList<>(); arrl.add("我"); arrl.add("想"); arrl.add("睡"); arrl.add("觉"); System.out.println(arrl); //ArrayList的父类AbstractCollection重写了toString()方法 arrl.forEach((str)->{ System.out.print(str + " "); }); /* * The default implementation behaves as if: for (T t : this) action.accept(t); * */ } } /* * 在JDK1.8中输出结果为: * ----------------- * [我, 想, 睡, 觉] 我 想 睡 觉 ------------------ * */
-
forEach例子一:自定义类型Employee类型的使用
public class TestForEach_2 { public static void main(String[] args) { ArrayList<Employee> all = new ArrayList<Employee>(); all.add(new Employee("haha",200,2018,7,23)); all.add(new Employee("xixi",200,2018,7,23)); all.add(new Employee("haxi",200,2018,7,23)); all.add(new Employee("xiha",200,2018,7,23)); all.forEach((str)->{ System.out.println(str); //调用Employee中的 }); } } class Employee{ //data field private String name; private double salary; private LocalDate hireDay; //constructor public Employee(String name,double salary,int year,int month,int day){ this.name = name; this.salary = salary; this.hireDay = LocalDate.of(year,month,day); } //method public String getName(){ return name; } public double getSalary(){ return salary; } public LocalDate gethireDay(){ return hireDay; } public void raiseSalary(double byPercent){ salary += salary * byPercent/100; } public String toString() { return "name : " + name + " salary : " + salary + "hireDay : " + hireDay; } }
四、集合框架(集合的遍历之Iterator遍历)
-
String类型的集合的遍历
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class TestIterator { public static void main(String[] args) { Collection<String> c = new ArrayList<String>(); c.add("哈哈哈"); c.add("好好好"); c.add("行行行"); Iterator<String> i = c.iterator(); while(i.hasNext()) { System.out.println(i.next()); } } } /* 在JDK1.8中输出结果为: ----- 哈哈哈 好好好 行行行 ---- */
-
自定义Employee类型的集合的遍历
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class TestIterator_2 { public static void main(String[] args) { Collection<Employee> c = new ArrayList<>(); c.add(new Employee("haha",200,2018,7,23)); c.add(new Employee("xixi",200,2018,7,23)); c.add(new Employee("haxi",200,2018,7,23)); c.add(new Employee("xiha",200,2018,7,23)); Iterator<Employee> i = c.iterator(); while(i.hasNext()) { Employee e = i.next(); System.out.println(e); } } } /* 在JDK1.8中输出结果为: -------------------- name : haha salary : 200.0hireDay : 2018-07-23 name : xixi salary : 200.0hireDay : 2018-07-23 name : haxi salary : 200.0hireDay : 2018-07-23 name : xiha salary : 200.0hireDay : 2018-07-23 * */
五、集合框架(迭代器的原理及源码解析)(了解)
-
迭代器原理
-
迭代器原理:迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿
-
迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可
-
六、集合框架(List集合的特有功能概述和测试)
-
List集合的特有功能概述
-
void add(int index,E element)
-
E remove(int index)
-
E get(int index)
-
E set(int index,E element)
-
七、集合框架(并发修改异常产生的原因及解决方案)
-
A:案例演示
-
需求:我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。
List list = new ArrayList(); list.add("a"); list.add("b"); list.add("world"); list.add("d"); list.add("e"); /*Iterator it = list.iterator(); while(it.hasNext()) { String str = (String)it.next(); if(str.equals("world")) { list.add("javaee"); //这里会抛出ConcurrentModificationException并发修改异常 } }*/
-
-
B:ConcurrentModificationException出现
- 迭代器遍历,集合修改集合
-
C:解决方案
-
a:迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)
-
b:集合遍历元素,集合修改元素
ListIterator lit = list.listIterator(); //如果想在遍历的过程中添加元素,可以用ListIterator中的add方法 while(lit.hasNext()) { String str = (String)lit.next(); if(str.equals("world")) { lit.add("javaee"); //list.add("javaee"); } }
-
八、集合框架(ListIterator)(了解)
- boolean hasNext()是否有下一个
- boolean hasPrevious()是否有前一个
- Object next()返回下一个元素
- Object previous();返回上一个元素
- 若想从后向前迭代,必须先从前往后迭代
九、Vector
-
Vector的实现方式是通过动态数组开辟的
-
与ArrayList唯一的区别在于:
- Vector线程安全,使用时效率不高
- ArrayList非线程安全
-
Vector中类似于Iterator的迭代器有:
- public Enumeration<E> elements();
- boolean hasMoreElements()
- E nextElement()
- public Enumeration<E> elements();
-
例子程序
public class TestVector { public static void main(String[] args) { Vector<String> v = new Vector<>(); v.add("hahaha"); v.add("xixixi"); v.add("hahaxi"); Enumeration<String> e = v.elements(); while(e.hasMoreElements()) { System.out.println(e.nextElement()); } } } /* * 在JDK1.8中输出结果为: * ------- * hahaha xixixi hahaxi ------- * */
十、集合框架(数据结构之数组和链表)
- A:数组
- 查询快修改也快
- 增删慢
- B:链表
- 查询慢,修改也慢
- 增删快
十一、_集合框架(List的三个子类的特点)
- List的三个子类的特点
-
ArrayList:
- 底层数据结构是数组,查询快,增删慢。
- 线程不安全,效率高。
-
Vector:
- 底层数据结构是数组,查询快,增删慢。
- 线程安全,效率低。
- Vector相对ArrayList查询慢(线程安全的)
- Vector相对LinkedList增删慢(数组结构)
-
LinkedList:
- 底层数据结构是链表,查询慢,增删快。
- 线程不安全,效率高。
-
Vector和ArrayList的区别
- Vector是线程安全的,效率低
- ArrayList是线程不安全的,效率高
-
共同点:都是数组实现的
-
ArrayList和LinkedList的区别
- ArrayList底层是数组结果,查询和修改快
- LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
-
共同点:都是线程不安全的
-
2.List有三个儿子,我们到底使用谁呢?
- 查询多用ArrayList
- 增删多用LinkedList
- 如果都多ArrayList
网友评论