JAVA学习日志9
集合
数组是用来存放相同数据类型的一个容器,长度是固定的。固定的长度有扩展性差。而集合也可以用来存储数据且长度不固定。
- 数组和集合
1.相同点:都可以用来存储数据 都可以通过索引来获取数据
2.不同点:数组长度不可变而集合长度是可变的 数组可以存基本数据类型也可以存引用数据类型,而集合只能存引用数据类型,当集合涉及到基本数据类型时使用其包装类 - 集合的架构
单列集合
双列集合
Collection
Collection 是一个接口不能实例话,只能实例化其子类,如 Collection col = new ArrayList();
-
一些方法
boolean add(E e) 向集合中添加(这里的E是范型) boolean contains(Object o) 集合中是否包含指定元素 boolean isEmpty() 判断集合中是否有元素 void clear() 清空集合中所以的元素 boolean remove(Object o) 删除集合中指定的数据 int size() 获取集合的长度 boolean addAll(Collection<? extends E> c) 集合的合并,把被调用者的元素追加到调用者里 boolean removeAll(Collection<?> c) 把调用者和被调用者中重合的部分 从调用者中移除(被调用者的不会发生任何改变) boolean containsAll(Collection<?> c) 判断被调用者的所有成员是否全部包含在调用者中 boolean retainAll(Collection<?> c) 真子集?
集合里的遍历方法(一)
把集合转换成数组来进行遍历,使用 Object[] toArray() 方法,遍历时使用数组的遍历方法
public static void main(String[] args) {
Collection<MyClass> list = new ArrayList<MyClass>();
list.add(new MyClass("No1","小明",19));
list.add(new MyClass("No2","小红",19));
//集合装换为数组
Object[]line= list.toArray();
//遍历输出
for(int i=0;i<line.length;i++) {
System.out.println(line[i].toString());
// MyClass temp = (MyClass)line[i];
// System.out.println(temp.getId()+" "+temp.getName()+" "+temp.getAge());
}
}
toString 方法在MyClass里进行了重写,所以object类里直接使用了MyClass的toString方法,若使用MyClass的其他特有方法,需要向下转型。
集合里的遍历方法(二)
使用迭代器 iterator来进行遍历
- 一些方法
boolean hasNext() 用于来判断是否有下一个元素 如果有返回 true 没有false E next() 返回下一个元素 void remove() 删除迭代器中的元素,删除的是当前指向的那个元素 Iterator iterator() 把集合转换成迭代器,由集合调用
public static void main(String[] args) {
Collection<MyClass> list = new ArrayList<MyClass>();
list.add(new MyClass("No1","小明",19));
list.add(new MyClass("No2","小红",19));
//把集合转换为迭代器
Iterator<MyClass> line = list.iterator();
//遍历输出
while(line.hasNext()) {
System.out.println(line.next().toString());
}
}
集合装换迭代器时,范型指明的了时MyClass类,所有ine.next()返回的也是MyClass类,故可以使用MyClass类里的一些特有方法
- 迭代器注意点:
1.迭代器需要先判断 hasNext() 然后再获取值
2.如果迭代器没有给泛型 默认返回都是Object 需要进行强制类型转换
3.next() 获取的是下一个元素 还会把指针往后进行移动
List接口
list是有序的,有索引的
- 一些方法( 都是根据索引来进行操作)
void add(int index,E element) 根据索引来进行增加 E set(int index, E element) 进行索引来进行修改 E remove(int index) 根据索引来进行删除 E get(int index) 根据索引得到具体的对象
集合里的遍历方法三
使用list的方法遍历
public static void main(String[] args) {
List<MyClass> list = new ArrayList<MyClass>();
list.add(new MyClass("No1","小明",19));
list.add(new MyClass("No2","小红",19));
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i).toString());
}
}
并发异常
用迭代器来进行遍历,使用集合来进行添加数据 会产生并发异常,如下面这样会产生ConcurrentModificationException
public static void main(String[] args) {
ArrayList<MyClass> list = new ArrayList<MyClass>();
list.add(new MyClass("No1","小明",19));
list.add(new MyClass("No2","小红",19));
//把集合转换为迭代器
Iterator<MyClass> line = list.iterator();
while(line.hasNext()) {
System.out.println(line.next().toString());
//使用集合添加元素
list.add(new MyClass("No3","小黑",19));
}
}
-
解决办法
1.使用迭代器来进行添加 使用迭代器来进行遍历
2.使用集合来进行遍历 使用集合来进行添加 -
使用迭代器来进行添加 使用迭代器来进行遍历
迭代器Iterator没有添加的元素的方法,所以需要使用到它的子类ListIterator,ListItreator不仅继承了Iterator的方法还有add()先当前指向的位置的下一位插入元素、 previous()获取前一个元素、hasPrevious()判断是否有前一个元素
public static void main(String[] args) {
ArrayList<MyClass> list = new ArrayList<MyClass>();
list.add(new MyClass("No1","小明",19));
list.add(new MyClass("No2","小红",19));
//把集合转换为迭代器
ListIterator<MyClass> line = list.listIterator();
while(line.hasNext()) {
System.out.println(line.next().toString());
//使用迭代器添加元素
line.add(new MyClass("No3","小黑",19));
}
}
添加完新元素后需要再次遍历集合才可以访问到新元素
ArrayList和LinkedList
ArrayList和LinkedList区别实际就是一维数组和链表的区别
- ArrayList没有自己独有的方法,其方法都是继承于list
- LinkedList 常用的方法:
public void addFirst(E e) 将指定元素插入此列表的开头 public void addLast(E e) 将指定元素添加到此列表的结尾 public E removeFirst() 移除并返回此列表的第一个元素 public E removeLast() 移除并返回此列表的最后一个元素 public E getFirst() 返回此列表的第一个元素 public E getLast() 返回此列表的最后一个元素
泛型
使用场景:当使用集合不确定其数据类型的时候,我就可以使用泛型 泛型可以理解为是一个变量 这个变量主要是用于来接收数据类型
-
泛型的好处:
1.提高代码的安全性 把运行错误的提前到编译出错
2.不需要进行反复强制类型转换 -
定义泛型使用一些字母 一般是大写 E T W K V
-
定义一个泛型类
访问修饰符 class 类名<泛型T,泛型W>{} -
给方法定义泛型
语法: 访问修饰 <泛型> 返回值类型 方法的名称(参数){}
注意点: 普通方法可以使用类的泛型,静态方法不能使用类的泛型 因为类的泛型在实例化的时候确定的 -
泛型定义接口
语法:interface 接口名<泛型T,泛型W>{}
实现类 :- 直接覆盖其泛型(也就是在实现类确定具体的泛型 )
- 实现类继续使用接口定义的泛型
-
范型的通配符
- ? 用于表示任意的类型 一般是用于方法传递参数的时候使用
public void show(List<?> list) { }
- <? extends E> 泛型只能是 E 泛型本身 或者是其子类
- <? super E> 泛型只能是 E 泛型本身 或者是其父类