Collection&Collection
存储5个学生—存储学生数组中 Student[] students = new Student[5] ; 数组中存储的引用类型,数组的弊端:长度是固定----java提供了"集合"
Collection 代表所有的单列集合,只能储存一种引用类型的集合
两个子接口 List / Set
基本功能:
boolean add(E e):添加任何类型元素 E---->理解为Object类型元素
boolean contains(Object o):判断集合中是否包含指定的元素
boolean isEmpty():判断集合是否为空
boolean remove(Object o):移出集合中的元素
void clear() :清空集合
int size():获取集合的元素数
Collection高级功能:
Object[] toArray() :将集合转换成对象数组
Iterator iterator() :Collection的专有遍历方式 (迭代器!)
//使用Collection集合存储5个不同的字符串,5个字符串遍历出来 (使用第一种方式存)
//创建Collection集合
Collection c = new ArrayList() ;
//5个不同的字符串
c.add("hello") ;
c.add("world") ;
c.add("javaee") ;
c.add("javase") ;
c.add("mysql") ;
System.out.println(c);
//Object[] toArray() :将集合转换成对象数组
Object[] objects = c.toArray();//相当于:Object obj = new String() ;
for(int x = 0 ; x < objects.length ; x++){
//System.out.println(objects[x]+"---"+objects[x].length());//objects[x]:Object类型
//不仅要字符串的内容,要输出字符串的长度------>length()--->String的特有功能
//向下转型 String
String s = (String) objects[x];
System.out.println(s+"---"+s.length());
}
Iterator
集合中专有遍历方式 ---------“迭代器”
Iterator iterator()
返回值是一个接口:
Iterator:
Object next()返回迭代中的下一个元素。 (返回任意java类型)
boolean hasNext():判断功能:判断迭代器中是否下一个元素
返回true,表示存在
返回false,不存在!
//先不用泛型<引用类型>
//创建Collection集合---- 具体的子实现类:ArrayList
Collection c = new ArrayList() ;
//创建5个学生对象
Student s1 = new Student("王昭君",35,"女") ;
Student s2 = new Student("杨贵妃",36,"女") ;
Student s3 = new Student("西施",25,"女") ;
Student s4 = new Student("貂蝉",20,"女") ;
Student s5 = new Student("高圆圆",43,"女") ;
//给里面存储
c.add(s1) ;
/* c.add("hello");
c.add("world") ;
c.add(100) ;*/
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
c.add(s5) ;
System.out.println(c);
//获取Collection集合的迭代器 Iterator iterator()
Iterator it = c.iterator() ;
//返回值是一个接口,iterator()方法底层一定是做了,需要返回的Iterator接口的子实现类对象
//迭代器接口: Object next()返回迭代中的下一个元素。 (返回任意java类型)
//第一次获取
//boolean hasNext():判断功能:判断迭代器中是否下一个元素
/* if(it.hasNext()){
Object next = it.next();//多态: Object next = new Student() 第一次存储s1,取出s1./s2/s3/s4...
System.out.println(next);
}
if(it.hasNext()){
//第二次获取
//直接输出
System.out.println(it.next());
}
if(it.hasNext()){
//第三次获取
System.out.println(it.next());
}
if(it.hasNext()){
//第四次获取
System.out.println(it.next());
}
if(it.hasNext()){
//第五次获取
System.out.println(it.next());
}*/
//没有加入判断出错了,因为迭代器中没有元素了
//第六次获取
//System.out.println(it.next());//java.util.NoSuchElementException :没有这样的元素的异常
//现在加入判断
/*if(it.hasNext()){
//第六次获取
//System.out.println(it.next());
}*/
//上面代码优化 模板代码使用while循环,因为这些数据以后都是从数据库中获取到的,循环次数不知道的,推荐while
while(it.hasNext()){
//获取下一个元素
// Object next = it.next();//本质多态:弊端不能使用子类特有功能 (向上转型)
//System.out.println(next); //执行的学生对象的toString()
//现在获取学生的getXXX()方法获取信息,不想使用上面代码
//it.next()---存储的是什么? 向下转型使用不当,就会出现ClassCastException类转换异常
// String s = (String) it.next(); //集合不使用泛型的弊端,当你接收类型出错,程序不安全!
// System.out.println(s) ;
Student s = (Student) it.next();
System.out.println(s.getName()+"----"+s.getAge()+"---"+s.getGender());
}
泛型
泛型:<引用类型> 集合中使用的
模拟 Java创建数组的时候就明确了数据类型
String[] str = {“hello”,“world”,100} ;//报错
int[] arr = {10,20,30,11,22,“hello”} ;//报错
1)创建集合的时候,就明确集合存储的引用类型的数据类型是什么!
2)可以有效防止程序不安全,通过的迭代器获取数据 next()—>返回值E (Object任意Java类型),
向下转型可能出问题,心里明确迭代器里面现在放的什么类型
3)不需要在强转了,避免了强转类型转换
*创建集合
举例
Collection c1 = new ArrayList<>() ;
//=号右边 后面的实例里面的<>可以不书写,也可以写,jdk7特性:泛型自动推断(不需要加)
//jdk提供内置注解 :注解本质是一个接口
@SuppressWarnings("all")// 压制警告(开发中,项目部署上线,所有java代码不能有警告线)
public class CollectionDemo3 {
public static void main(String[] args) {
//加入泛型的操作
//创建集合
Collection<Student> c = new ArrayList<>() ;//现在这个集合中只能存储Student类型
//创建5个学生
Student s1 = new Student("秦昊",23,"男") ;
Student s2 = new Student("张波",25,"男") ;
Student s3 = new Student("高珊",22,"女") ;
Student s4 = new Student("郑超帆",20,"男") ;
Student s5 = new Student("高圆圆",30,"女") ;
//添加到集合中
//c.add("hello") ; 不能存储其他类型
c.add(s1) ;
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
c.add(s5) ;
//获取Collection集合的迭代器
//Iterator<E> iterator()
//迭代器的泛型和集合中存储的泛型一致
Iterator<Student> it = c.iterator();
//遍历
while(it.hasNext()){//是否有下一个元素
//获取
Student s = it.next();//避免强转了
System.out.println(s); //toString
System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGender());
}
}
}
18.day18
List
List集合特点:
- 元素可以重复
- 储存和取出一致(有序性)
List 集合 继承Collection 接口,目前存储字符串,并遍历? 有几种方式
Object[] toArray() 将集合转换成对象数组
Iterator iterator() Collection 的迭代器
自己的特有遍历方式 List </>
普通 for()循环 : 使用集合 int size() : 获取元素数
E get(int index):通过角标获取元素
集合的列表迭代器 ListIterator listiterator()
ListIterator:
boolean hasNext(): 是否有下一个元素
E next(): 获取下一个元素
List<String> list = new ArrayList<>() ;
list.add("hello") ;
list.add("world") ;
list.add("javaEE") ;
list.add("android") ;
for(int x= 0 ;x < list.size();x++){
//通过角标获取元素
// E get(int index):通过角标获取元素 ,返回值类型和集合存储的类型一致
String s = list.get(x);
System.out.println(s);
}
/**
* 集合的列表迭代器ListIterator listiterator() :默认正向遍历
* ListIterator:
* boolean hasNext():是否有下一个元素
* E next():获取下一个元素
*
* 反向遍历
* boolean hasPrevious():判断是由上一个元素
* E previous():获取上个元素
* 必须先有正向遍历,才有反向遍历
*
*
*/
ListIterator<String> lit = list.listIterator();//获取List集合专有迭代器
while(lit.hasNext()){//判断是否有下一个元素,有才获取
String s = lit.next();//获取下一个元素
System.out.println(s) ;
}
System.out.println("---------反向遍历-------------");
/**
* 反向遍历
* boolean hasPrevious():判断是由上一个元素
* E previous():获取上个元素
* 必须先有正向遍历,才有反向遍历
*/
while(lit.hasPrevious()){
String s = lit.previous();
System.out.println(s);
}
增强for
最终的写法:开发中写的,增强for循环:jdk5的新特性
增强for循环的出现目的:是为了代替迭代器的使用(为了简化代码的书写),一般在集合中用
增强for循环遍历数组少,数组:建议普通循环
for(集合中存储的类型 变量名:集合对象或者数组对象){
使用这个变量名即可!
}
ArrayList
底层数组,查询快,增删慢,线程考虑安全(普遍用,效率高)
数组和集合的区别
- 长度区别
- 数组长度固定
- 集合长度可变
- 存储数据类型的区别
- 数组: 存储的数据类型: 可以是基本类型,也可以是引用类型
- 集合: 存储的数据类型: 只能使用引用类型
- 存储元素的区别
- 数组: 只能存储一种数据类型的数据
- 集合: 可以存储不同的数据类型
List集合自定义对象去重
ist list集合存储自定义对象并去保证元素唯一
Student类:自定义的类
分析:
1)假设就创建List集合对象,里面存储重复的字符串数据
2)创建一个新的List集合,空集合
3)遍历以前的集合,获取以前的所有元素,在新的集合中判断,是否包含这个
元素,如果不包含,说明不重复将元素添加到新集合中,如果包含,说明重复,重复元素不需要加入到新集合
中(找考虑不包含的情况)4)最终,遍历新的集合,就是一个不重复的元素!
刚才存储List String类----jdk提供的
刚才存储重复的字符串并保证元素唯一,里面用到集合的contains(Object a)
里面依赖于一个indexof
public boolean contains(Object o) {
return indexOf(o) >= 0; //查询元素
}
indexOf方法又依赖于Object的equals方法,—>contains(Object o)间接依赖于
Object的equals方法而List,里面是String类型,本身重写了Object的equals方法,所以比较
的是字符串内容是否相同但是我们List,自定义的类型,所有必须重写Object的equals(),
才能比较的是对象的成员信息是否相同,相同认为是同一个人
不重写比较的就是地址值是否相同
LinkedList
底层链表 ( 添加.删除/修改比较快, 查询比较慢的)
特点
底层数据结构是一种链表,链表的特点:查询慢(每次需要冲链表头查询到末尾),增删快;线程不安全的,不同步,执行比较高!
特有功能
- public void addFirst(E e):添加到链表的开头
- public void addLast(E e):添加到链表的末尾
- public E getFirst():获取链表的第一个元素
- public E getLast():获取链表的末尾的元素
- public E removeFirst():删除链表第一个元素
- public E removeLast():删除链表的最后一个元素
- public void push(E e):推送到链表开头(压栈)—等价于public void addFirst(E e):添加到链表的开头
- public E pop():弹出最后一个元素(弹栈) 等于removeFirst() :将第一个元素删除并返回
面试题
面试的编程题
使用LinkedList的特有功能模拟栈结构特点?
栈结构:先进后出
相当于自定义一个类,这个类完成一些功能,需要使用到LinkedList集合的特有功能
这个功能添加元素(压栈)—>使用LinkedList的addFirst():每一次将元素添加到链表开头
获取元素:(弹栈)----->使用LinkedList集合的removeFist():相当于pop:弹栈,删除第一个并获取第一个元素
Vector
:底层数组( 效率低, 安全 )
特点
Vector集合底层数据结构数组,(查询,更新元素比较快,添加,删除比较麻烦的),
线程安全的类—同步的—执行效率比较低(多线程环境下使用安全性比较大的类)
是List集合接口子实现类之一,遍历元素能够List的五种方式
但是它有自己的特有功能
特有功能
添加元素
public void addElement(E obj):添加任意元素 如果E类型确定了,就只能添加这个数据类型
类似于 集合的通用功能add(E obj)
遍历元素方式1
public Enumeration elements():获取组件(返回值是枚举接口—产生一系列元素)
类似于Collection集合的Iterator iterator()迭代器
Enumeration枚举接口
boolean hasMoreElements() 判断是有更多的元素
—>类似于Iterator迭代器里面的hasNext()
E nextElement() :获取下个元素
—>类似于Iterator迭代器里面的next():获取下一个元素
遍历元素方式2
public E elementAt(int index)通过角标获取元素 —类似于List集合的public E get(int index)
结合 int size()获取集合长度(集合元素数量)
/**
* Enumeration枚举接口
* boolean hasMoreElements() 判断是* 有更多的元素
* --->类似于Iterator迭* 代器里面的hasNext()
* E nextElement() :获取下个元素
* --->类似于Iterator * 迭代器里面的next():获取下一个元素
*/