枚举
枚举 enum
- 可以用来表示一种事物的所有可能
注意:
1.枚举都隐示的继承自java.lang.Enum
2.枚举也是一种比较特殊的类,枚举中得饿所有成员都是当前枚举类的一个实例(对象),成员默认public static final修饰
3.不允许外部实例化,只能使用枚举类中提供的成员
格式:
enum 枚举类型名{
枚举值,枚举值2,枚举值3
}
public class EnumDemo01 {
public static void main(String[] args) {
//new Student().weekday = WeekDay.Mon;
//枚举类型实例的获取
Week w = Week.Sun;
//成员名字
System.out.println(w.name());
//索引
System.out.println(w.ordinal());
//w.setName("周日");
System.out.println(w.getName());
w.test();
//判断枚举类型的
switch(w) {
case Mon:
System.out.println("周一");
break;
case Sun:
System.out.println("周天");
break;
}
}
}
//枚举类
enum Week{
//枚举的成员,当前 枚举类的实例(对象),这些由我们程序员指定,只能有这些,不能外部new实例化-->所以称为当前这个类的所有可能
Mon,Tue,Sun("第七天",10); //Sun("第七天") ->Sun对象名 (参数)-->构造器的实参
//属性
private String name;
private int num;
private Week() { // TODO Auto-generated constructor stub
}
private Week(String name) {
this.name = name;
}
private Week(String name, int num) {
this.name = name;
this.num = num;
}
public String getName() {
return name;
}
public void test() {
System.out.println("今天是"+name);
}
}
//提高是星期几的实例
class WeekDay{
public static final WeekDay Mon = new WeekDay(); //周一
}
class Student{
String name;
WeekDay weekday ; //表示 周几入学
}
容器
之前我们学习过数组,数组是相同数据类型的有序集合,可以在其中放置对象或基本类型数据,说白了就是容器。数组是一种简单的线性序列,可以快速的访问数组元素,效率高。如果从效率和类型检查的角度讲,数组是最好的。但是从数组长度一旦确定,不可改变,因此,不灵活:容量需要事先定义好,不能随着需求的变化而扩容。
比如: 我们在一个用户管理系统中,要把今天注册的所有用户取出来,那么这个用户有多少个?我们在写程序时是无法确定的。如果,你能确定那你就是神了。因此,就不能使用数组。因此,数组远远不能满足我们的需求。我们需要一种灵活的,容量可以随时扩充的容器来装载我们的对象。这就是我们今天要学习的容器类,或者叫集合框架。
Collection
接口是一组允许重复的对象。
Set
接口继承 Collection
,无序不允许重复,使用自己内部的一个排列机制。
List
接口继承Collection
,有序允许重复,以元素安插的次序来放置元素, 不会重新排列。
Map
接口是一组成对的键值对象,即所持有的是key-value pairs
。Map
中不能有重 复的 key
。拥有自己的内部排列机制。
容器中的元素类型都为引用类型,不能放置原生数据类型(使用装箱即可),使用泛 型保留类型
import java.util.ArrayList;
import java.util.List;
/**
- 数组和容器: 都可以存储多个数据
- 数组的特点:
- 有序,索引
- 数据类型一致
- 长度一旦确定不可改变
-
- 容器:
- 容器的长度可以根据数据的多少自动增删
- 是引用是引用数据类型
- 容器中可以存储任意类型的数据
- @author yinwei
*/
public class ContainerDemo01 {
public static void main(String[] args) {
Person[] arr = {new Person(),new Person()} ;
System.out.println(arr.length);
//容器的使用
List list = new ArrayList();
list.add("zhangsan");
list.add(123);
list.add(new Person());
System.out.println(list.size());
list.add(new Person());
System.out.println(list.size());
System.out.println(list);
list.remove(0);
System.out.println(list.size());
System.out.println(list.get(-1));
}
}
class Person{}
Collection 接口
Collection
表示一组对象,它是集中,收集的意思,就是把一些数据收集起来,Collection
接口的两个子接口:
Set
中的数据没有顺序,不可重复
List
中的数据有顺序,可重复
package com.xxxx.collection03;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
- 容器中只能存放引用数据类型的数据
- Collection:
- 一些实现类可重复有序List 一些不可冲无序Set
- *定义自定义的引用数据类型的数据,存放在容器中ArrayList
- 遍历方式:
- 1.增强for foreach
- 2.迭代器
*/
public class CollectionDemo01 {
public static void main(String[] args) {
Collection coll = new ArrayList();
Collection coll2 = new ArrayList();
Collection coll3 = new ArrayList();
coll.add(123); // 自动装箱
coll.add(456); // 自动装箱
//添加
coll2.add("000");
System.out.println(coll2);
coll2.addAll(coll);
System.out.println(coll2);
System.out.println(coll);
//清空
coll.clear();
System.out.println(coll);
//boolean contains(Object o) 包含
System.out.println(coll2.contains("000"));
coll3.addAll(coll2);
//boolean equals(Object o) 比较内容是否相等
System.out.println(coll2.equals(coll3));
//boolean remove(Object o) 移除
System.out.println(coll2.remove(123));
coll2.add(false);
System.out.println(coll2);
//boolean retainAll(Collection<?> c) 交集
System.out.println(coll3.retainAll(coll2));
System.out.println(coll2);
System.out.println(coll3);
//遍历 foreach
for(Object o: coll2) {
System.out.println(o);
}
//迭代器
//1.获取容器的迭代器
Iterator it = coll2.iterator();
//2.循环判断是否存在下一个元素
while(it.hasNext()) {
//3.获取
System.out.println(it.next());
}
}
}
<> 泛型
把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型
为什么需要泛型?
JDK1.4 以前类型不明确:
装入集合的类型都被当作Object
对待,从而失去自己的实际类型。
从集合中取出时往往需要转型,效率低,容易产生错误。
泛型的好处:
增强程序的可读性和稳定性。*
使用泛型,保留了容器中元素的类型,安全省心的使用容器。注意:没有必要引入泛型 的复杂性。
Collection<String> col =new ArrayList<String>();
//添加
col.add("字符串1");
col.add("字符串1");
col.add("字符串1");
Iterator接口
所有实现了Collection
接口的容器类都有一个iterator
方法用以返回一个实现了Iterator
接口的对象。Iterator
对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
使用迭代器时,分三步走策略:
第一步:获取对象
第二步:判断是否存在下一个
第三步:获取元素
迭代器迭代元素的过程中不能使用集合对象的remove
方法删除元素,
要使用迭代器Iterator
的remove
方法来删除元素,防止出现异常:
ConcurrentModificationException
//迭代器
//1.获取容器的迭代器
Iterator it = coll2.iterator();
//2.循环判断是否存在下一个元素
while(it.hasNext()) {
//3.获取
System.out.println(it.next());
}
//Iterator接口定义的方法
boolean hasNext(); //判断是否有元素没有被遍历
Object next(); //返回游标当前位置的元素并将游标移动到下一个位置
void remove(); //删除游标左面的元素
List接口
List
接口中的常用方法。
List
是Collection
接口的子接口。所以List
接口中有一些特有的方法。
void add(int index, Object element)
Object set(int index, Object element)
Object get(int index)
int indexOf(Object o)
int lastIndexOf(Object o)
Object remove(int index)
public class ListDemo01 {
public static void main(String[] args) {
//准备一个List容器,存放我喜欢的电影名字
//泛型: 规定使用数据的类型-->好处增强程序的可读性和稳定性。
//只能存放字符串类型
List<String> list = new ArrayList<String>();
list.add("记忆碎片 ");
list.add("无间道");
list.add("星际穿越");
list.add("后来的我们");
System.out.println(list);
//void add(int index, E element)
list.add(3, "时间规划局");
list.add(5,"无间道");
System.out.println(list);
//E get(int index)
System.out.println(list.get(2));
//int indexOf(Object o)
System.out.println(list.indexOf("无间道")); //1
System.out.println(list.lastIndexOf("无间道")); //1
//remove()
System.out.println(list.remove(4));
//测试 如果存储的数据是数字,remove以索引还是内容为主?????
// E set(int index, E element)
System.out.println(list.set(4, "头号玩家"));
System.out.println(list);
}
}
遍历方式:
- 普通for
- foreach
- 迭代器iterator
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/*
- 定义一个List容器,存放你喜欢的漫威人物,判断如果里面有灭霸,就添加一个惊奇队长!!!
- */
public class ListDemo02 {
public static void main(String[] args) {
List<String> list = new ArrayList();
list.add("钢铁侠");
list.add("寇尔森");
list.add("灭霸");
list.add("死侍");
list.add("蚁人");
//1. constains
// if(list.contains("灭霸")) {
// list.add("惊奇队长");
// }
// System.out.println(list);
System.out.println(list);
//2.for
// for(int i =0;i<list.size();i++) {
// if("灭霸".equals(list.get(i))) {
// list.add("惊奇队长");
// }
// }
// System.out.println(list);
```
//2.foreach -->java.util.ConcurrentModificationException
```
// for(String s:list) { //给泛型了才能使用String,否则使用Object
// if("灭霸".equals(s)) {
// list.add("惊奇队长");
// }
// }
// System.out.println(list);
```
//迭代器 iterator ConcurrentModificationException
```
// for(Iterator<String> it = list.iterator();it.hasNext();) {
// if("灭霸".equals(it.next())) {
// list.add("惊奇队长");
// }
// }
// System.out.println(list);
//ListIterator列表迭代器
ListIterator it2 = list.listIterator();
while(it2.hasNext()) {
if("灭霸".equals(it2.next())) {
it2.add("11111");
}
}
System.out.println(list);
//逆向遍历
//boolean hasPrevious()
// E previous()
}
}
AarryList、Vector和LinkedList
AarryList
:
- 底层实现: 可变数组实现的,内部 通过数组拷贝实现根据内容可变长
- 优点 : 根据索引查询效率高
- 缺点 :错增加删除时效率低,因为要通过数组拷贝实现
- 应用场景: 存储耽搁数据,有序可以重复–>大量做查询,少量增删,推荐使用ArrayList
- 扩容: 在第一次添加数据时候初始容量10 , 通过Arrays.copyof方法进行动态扩容,每次扩容原容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
Vector
:
*底层实现: 可变数组实现的,
- 扩容:: 在第一次添加数据时候初始容量10 , 每次扩容原容量的2倍
- 与ArrayList不同点: 1)AarryList线程不安全 ,vector线程安全 2)扩容问题: ArrayList1.5倍增长 vector2倍增长 ArrayList更有利于节省内存
LinkedList
:
-
底层实现: 双向链表实现的
-
优点:增删效率高
-
缺点: 查询效率低
-
应用场景: 存储耽搁数据,有序可以重复–>如果做大量的增删,少量的查询,推荐使用LinkedList
1)不安全 ,vector
线程安全
2) 扩容问题: ArrayList
1.5倍增长 vector
2倍增长 ArrayList
更有利于节省内存
`