标签:超过 ceo 后续遍历 接受 原则 破坏 特性 区别 bsp
传统的容器(数组)在进行增、删等破坏性操作时,需要移动元素,可能导致性能问题;同时添加、删除等算法和具体业务耦合在一起,增加了程序开发的复杂度。
Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中
Collection是java集合框架(collection-frame)中的顶层接口。
Collection接口是一个容器,容器中只能存储引用数据类型,建议存同一类型的引用类型,方便后续遍历等操作。
容器中的元素可以是有序的、可重复的,称为List接口
也可能是无序的、唯一的,称为Set接口。
public static void main(String[] args) {
/**
* 增:add/addAll
* 删:clear/remove/removeAll/retainAll
* 改:
* 查:contains/containsAll/isEmpty/size
*/
Collection c1 = new ArrayList();
// 追加
c1.add("apple"); // Object object = new String("apple");
// c1.add(1); // Object object = new Integer(1);
c1.add("banana");
System.out.println(c1);
// 追加一个集合
Collection c2 = new ArrayList();
c2.add("java");
c2.add("c++");
c1.addAll(c2);
System.out.println(c1);
// clear
//c1.clear();
// c1.remove("apple");
// c1.removeAll(c2);
//c1.retainAll(c2);
//System.out.println(c1);
System.out.println(c1.contains("apple"));
c2.add("js");
System.out.println(c1.containsAll(c2));
// c1.clear();
System.out.println(c1.isEmpty());
// 返回集合元素的个数
System.out.println(c1.size());
System.out.println(c1.equals(c2));
}
Iterable 可遍历的接口,集合接口继承于它,集合支持快速遍历。
// 快速遍历
// for-each
// Object 表示元素类型
// item表示迭代变量
// c1表示集合
for (Object item : c1) {
System.out.println(item.toString());
快速遍历的本质
Collection继承Iterable接口,表示集合支持快速遍历。Iterable接口定义了一个方法iterator()用于获取集合的迭代器,是一个Iterator接口类型,iterator()内部返回一个实现类实现类Iterator接口。这个实现类一定具有hasNext和next方法用于判断是否有下一个元素和获取下一个元素。快速遍历就是基于迭代器工作的。
public static void main(String[] args) {
Collection c1 = new ArrayList();
c1.add("apple");
c1.add("banana");
c1.add("coco");
// 快速遍历
// for-each
// Object 表示元素类型
// item表示迭代变量
// c1表示集合
for (Object item : c1) {
System.out.println(item.toString());
}
// 迭代器遍历(国内)
Iterator it = c1.iterator();
while(it.hasNext()) {
Object item = it.next();
System.out.println(item.toString());
}
// 国外
for(Iterator it2=c1.iterator();it2.hasNext();) {
Object item = it2.next();
System.out.println(item.toString());
}
}
List 接口中的元素时有序的、可重复的。List接口中的元素通过索引(index)来确定元素的顺序。
有序的 collection(也称为序列)。可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素
public static void main(String[] args) {
/**
* 增:add/addAll/add(index,el)/addAll(index,collection)
* 删:clear/remove/removeAll/remove(index)
* 改:set(index,el)
* 查:get(index)/indexOf/lastIndexOf()
* 其他:contains/containsAll/isEmpty/size
*/
List list1 = new ArrayList();
// 添加元素
list1.add("apple");
list1.add("banana");
// 在指定位置添加元素
list1.add(0, "coco");
System.out.println(list1);
List list2 = new ArrayList();
list2.add("java");
list2.add("c++");
list1.addAll(1, list2);
System.out.println(list1);
// 删除
list1.remove(0);
System.out.println(list1);
// 修改
list1.set(0, "javax");
System.out.println(list1);
// 查
System.out.println(list1.get(0));
list1.add("apple");
list1.add("apple");
System.out.println(list1);
System.out.println(list1.indexOf("apple"));
System.out.println(list1.lastIndexOf("apple"));
}
ListIterator 继承于Iterator,在Iterator的基础上提供了以正向遍历集合,也可以以逆序遍历集合。
hasNext/next 以正向遍历
hasPrevious/previous 以逆序遍历
public static void main(String[] args) {
List list1 = new ArrayList();
list1.add("apple");
list1.add("banana");
list1.add("coco");
// 【1】快速遍历
System.out.println("--for each--");
for (Object item : list1) {
System.out.println(item.toString());
}
// 【2】普通for
System.out.println("--for--");
for(int i=0;i<list1.size();i++) {
System.out.println(list1.get(i));
}
// 【3】集合迭代器
System.out.println("--iterator--");
Iterator it = list1.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
System.out.println("--list iterator--");
// 正向遍历
ListIterator it2 = list1.listIterator();
while(it2.hasNext()) {
System.out.println(it2.next());
}
// 逆序遍历
while(it2.hasPrevious()) {
System.out.println(it2.previous());
}
System.out.println("--list iterator with index--");
ListIterator it3 = list1.listIterator(1);
while(it3.hasNext()) {
System.out.println(it3.next());
}
}
数据结构就是数据在内存中存储结构。根据存储的方式不同,分为线性表、二叉树、图、栈、队列等
线性表数据按照一定的逻辑顺序存储在内存中。线性表是有序的。线性表根据内存的物理结构分为两种:数组和链表
数组是一种逻辑上有序的线性表,物理上也连续。
数组和链表的区别
相同点
不同点
数组在查询时效率高,在添加、删除元素时效率低(涉及移动元素)
链表在查询时效率低(每次从头开始,不能跳跃访问),在添加、删除元素时效率高(不涉及移动元素)
特性:先进后出,后进先出
ArrayList 是List接口的实现类,底层数据结构是数组,实现大小可变的数组。
ArrayList 线程不安全,jdk1.2
ArrayList 底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,ArrayList会自动拓容,拓容原则:newCapacity = oldCapacity + oldCapacity / 2;
如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。
ArrayList作为List接口的实现类,常用方法和遍历方法参考List接口。
Vector 是List接口的实现类,底层数据结构也是数组,也是大小可变的数组。
Vector是线程安全的,jdk1.0
Vector底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,Vector会自动拓容,拓容原则:newCapacity = oldCapacity +capacityIncrement(增长因子);如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。
注意:Vector 在实现List接口的同时,同添加了自身特有的方法xxxElement,未来使用时为了程序的可拓展性,一定要按照接口来操作Vector。
LinkedList是List接口的实现类,底层数据结构是链表。
LinekList常用方法和遍历方法参照List接口。
LinkedList 线程不安全。
public class Test01 {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.push("apple");
list.push("banana");
list.push("coco");
System.out.println(list.pop());
System.out.println(list.pop());
System.out.println(list.pop());
// java.util.NoSuchElementException
System.out.println(list.pop());
}
}
public static void main(String[] args) {
LinkedList queue = new LinkedList();
// 入队
/**
* 队列头 队列尾
*<----- <-----
* [apple, banana, coco]
*/
queue.add("apple");
queue.add("banana");
queue.add("coco");
System.out.println(queue);
// 出队
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue);
// java.util.NoSuchElementException
System.out.println(queue.remove());
// 获取表头元素
System.out.println(queue.element());
}
public static void main(String[] args) {
LinkedList queue = new LinkedList();
// 入队
/**
* 队列头 队列尾
*<----- <-----
* [apple, banana, coco]
*/
queue.offer("apple");
queue.offer("banana");
queue.offer("coco");
// 出队列
//System.out.println(queue.poll());
//System.out.println(queue.poll());
//System.out.println(queue.poll());
System.out.println(queue);
//System.out.println(queue.poll());
// 获取表头元素
System.out.println(queue.peek());
}
/**
* 以双向队列形式操作LinkedList
*/
public class Test04 {
public static void main(String[] args) {
LinkedList queue = new LinkedList();
// 入队
/**
*<----- <-----
* [apple, banana, coco]
* ----> ----->
*/
queue.addFirst("apple");
queue.addFirst("banana");
queue.addFirst("coco");
System.out.println(queue);
System.out.println(queue.removeLast());
System.out.println(queue.removeFirst());
System.out.println(queue.removeFirst());
System.out.println(queue);
// 获取头元素
System.out.println(queue.getFirst());
}
}
Iterator在迭代过程中不允许向集合中添加元素
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("apple");
list.add("banana");
list.add("coco");
Iterator it = list.iterator();
while(it.hasNext()) {
String item = (String) it.next();
if(item.equals("banana")) {
list.add("test");
}
}
System.out.println(list);
}
当通过Iterator集合迭代器遍历集合过程中,不能再向集合汇总添加元素,否则出现ConcurrentModificationException 并发修改异常。
ListIterator允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置
public class Test01 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("apple");
list.add("banana");
list.add("coco");
ListIterator it = list.listIterator();
while(it.hasNext()) {
String item = (String) it.next();
if(item.equals("banana")) {
it.add("test");
}
}
System.out.println(list);
}
}
泛型允许开发者在强类型程序设计语言(java)编写代码时定义一些可变部分,这些部分在使用前必须作出指明。
泛型就是将类型参数化
ArrayList<E> list表示声明了一个列表list,列表的元素是E类型 |
ArrayList<String> list = new ArrayList<String>(); 声明了一个列表list,列表的元素只能是String类型。 |
泛型在运行时已经被擦除了
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("apple");
System.out.println(list instanceof ArrayList);
System.out.println(list instanceof ArrayList<String>);
Cannot perform instanceof check against parameterized type ArrayList<String>. Use the form ArrayList<?> instead since further generic type information will be erased at runtime
当一个类中属性的数据类型不确定时,具体是什么类型由使用者来确定时,使用泛型。泛型类的形式
public class FanClass<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public FanClass(T t) {
super();
this.t = t;
}
public FanClass() {
super();
}
}
public static void main(String[] args) {
FanClass<String> fan = new FanClass<String>();
fan.setT("apple");
FanClass<Integer> fan2 = new FanClass<Integer>();
fan2.setT(1);
}
}
当一个方法的参数类型不确定时,具体是什么类型由使用者来确定,可以考虑使用泛型方法。形式
public <T> void xxx(T a) {
System.out.println(a);
}
public class Student {
/*public void showInfo(int a) {
System.out.println(a);
}
public void showInfo(float a) {
System.out.println(a);
}
public void showInfo(String a) {
System.out.println(a);
}*/
public <T> void showInfo(T a) {
System.out.println(a);
}
}
public static void main(String[] args) {
Student stu = new Student();
stu.showInfo(1);
stu.showInfo("apple");
stu.showInfo(1.0f);
}
泛型方法在调用时确定(指明)类型。
泛型方法在一定程度上优化了方法重载。
泛型方法可以定义多个泛型类型
可以定义多个泛型的类型
public <A,B> void showInfo(A a,B b) {
System.out.println(a);
System.out.println(b);
}
多个泛型类型进一步优化了方法重载。
多个同类型的泛型
/ 多个同类型的泛型
/*public <A> void print(A a) {
System.out.println(a);
}
public <A> void print(A a,A b) {
System.out.println(a);
System.out.println(b);
}*/
public <A> void print(A...a) {
System.out.println(a);
}
A… a 表示方法可以接受多个参数。当调用方法传递多个参数时,多个参数被放到a数组中,a是什么类型的数组由开发者调用处传参决定。
stu.print(1); stu.print(1,2);
stu.print("apple"); stu.print("apple","banana"); |
print(A...a) 方法称为可变参数的泛型形式。
标签:超过 ceo 后续遍历 接受 原则 破坏 特性 区别 bsp
原文地址:https://www.cnblogs.com/gflb/p/10797807.html