集合
集合的特点
1.集合能够对数据进行增加删除修改查询的操作
2.集合能够存储引用类型,如果是基本类型可以是包装类类型
3.集合的长度是可变的
4.部分集合是有序的,部分集合是无序的 (这里的有序指的是存储有序,并不是排序)
5.部分集合是唯一的,部分集合是可重复 (11, 22 ,33, 33, 22)
6.部分集合是可排序的,部分集合是不可排序的
7.部分集合是线程安全的,部分集合是线程不安全 (synchronized)
##### 常见的和集合相关的数据结构数组,栈,队列,链表,哈希表,二叉树 . 存储方式不一样决定了该集合的性能效率不一样
##### 集合常用的方法1.增加功能
2.删除功能
3.修改功能
4.查询功能
5.获取功能
6.判断功能
7.其他功能
public class Test09 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("张三");
c.add("李四");
c.add("王五");
c.add("赵六");
System.out.println(c); // [张三, 李四, 王五, 赵六]
// boolean addAll(Collection c)
Collection c2 = new ArrayList();
c2.add("小红");
c2.add("小明");
c2.add("小芳");
c.addAll(c2);
System.out.println(c);//[张三, 李四, 王五, 赵六, 小红, 小明, 小芳]
// boolean remove(Object o)
System.out.println("remove: " + c.remove("张三"));//remove: true
System.out.println(c);//[李四, 王五, 赵六, 小红, 小明, 小芳]
// boolean removeAll(Collection<?> c);
// System.out.println("removeAll: " + c.removeAll(c2));//删除c里面的c2
// System.out.println(c);
// void clear()
// c.clear();//清空
// System.out.println(c);
System.out.println(c.size());//6
System.out.println("contains: " + c.contains("李四"));//是否有这个元素:true
System.out.println("contains: " + c.contains("曹操"));//false
System.out.println("contains: " + c.contains(""));//false
System.out.println("containsAll: " + c.containsAll(c2));//true
System.out.println("isEmpty: " + c.isEmpty());//是否为空
Collection c3 = new ArrayList();
// c3.add("张三");
// c3.add("李四");
// c3.add("王五");
// c3.add("赵六");
// c3.add("小红");
// c3.add("小明");
// c3.add("小芳");
// c3.add("小李");
System.out.println(c);//[李四, 王五, 赵六, 小红, 小明, 小芳]
System.out.println(c3);//[]
System.out.println("retainAll:" + c.retainAll(c3));//retainAll:true
System.out.println("c:" + c);//c:[]
}
}
集合的遍历
public class CollectionDemo02 {
public static void main(String[] args) {
// Object[] toArray()
Collection c = new ArrayList();
c.add("希特勒");
c.add("杨贵妃");
c.add("貂蝉");
c.add("赛西施");
// c.add(c);
// c.add(100);
System.out.println(c);
// Object[] objs = c.toArray();
// for (Object oj : objs) {
// String s = (String) oj;
// System.out.println(s);
// }
// Iterator<E> iterator()
// 获取迭代器对象
Iterator it = c.iterator();
// Object oj = it.next();
// System.out.println(oj);
//
// oj = it.next();
// System.out.println(oj);
//
// oj = it.next();
// System.out.println(oj);
//
// oj = it.next();
// System.out.println(oj);
//
// oj = it.next();
// System.out.println(oj);
while (it.hasNext()) {//it.hasNext()判断是否还有下一个元素
Object oj = it.next();
System.out.println(oj);
}
}
}
集合的并发修改异常
== java.util.ConcurrentModificationException==
产生原因: 表示在使用迭代器的同时,使用原集合修改了元素
解决办法:
1.只操作原集合
toArray
普通for
2.只操作迭代器
使用ListIterator
注意:
foreach遍历集合底层也是使用了迭代器不能够解决并发修改异常
修改异常小案例
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("希特勒");
c.add("杨贵妃");
c.add("貂蝉");
c.add("赛西施");
// Iterator it = c.iterator();
// while (it.hasNext()) {
// Object oj = it.next();
// String s = (String) oj;
// if (s.equals("杨贵妃")) {
// c.remove("杨贵妃");
// }
// }
// Object[] objs = c.toArray();
// for (Object oj : objs) {
// String s = (String) oj;
// if (s.equals("杨贵妃")) {
// c.remove("杨贵妃");
// }
// }
// for (Object oj : c) {
// String s = (String) oj;
// if (s.equals("杨贵妃")) {
// c.remove("杨贵妃");
// }
// }
// for (Iterator iterator = c.iterator(); iterator.hasNext();)
// {
// Object oj = iterator.next();
// String s = (String)oj;
// if (s.equals("杨贵妃"))
// c.remove("杨贵妃");
// }
// for(Iterator iterator = c.iterator();iterator.hasNext();) System.out.println(iterator.next());
}
泛型
泛型的概念
在编译时期就确定的类型的一种技术 ,泛型是一种参数化类型
泛型是JDK1.5之后引入的新特性,是一种将引用类型当做参数传递的参数化类型,在编译时期就已经确定了集合存储的元素类型
格式:
<数据类型> 这里的类型必须是引用类型
1. <>里面可以是任意的字母,一般泛型类会使用E,泛型方法会使用T
2. 这里只能够定义引用类型,不能够定义基本书类型
3. <>里面既可以定义一个泛型,也可以定义多个泛型
泛型的好处
1.提高了程序的安全性
3.在编译时期将类型确定,减少不必要的强转代码
泛型的应用
泛型根据放置的位置不同分为
泛型类
泛型接口
泛型方法
没有用泛型的案例
for (Iterator it = c.iterator(); it.hasNext(); ) {
Object oj = it.next();
if (oj instanceof String) {
// 访问子类每一个元素所特有的方法
String s = (String) oj;
System.out.println("字符串的长度" + s.length());
} else if (oj instanceof Integer) {
Integer i = (Integer) oj;
System.out.println("整数的值: " + i.intValue());
} else if (oj instanceof Double) {
Double d = (Double) oj;
System.out.println("小数的值: " + d.doubleValue());
}
}
用了泛型的案例
Collection<String> c = new ArrayList<String>();
c.add("张三");
c.add("李四");
c.add("王五");
// c.add(20);
// c.add(2.5);
// c.add(new Student("1001", "张三", 30));
Iterator<String> it = c.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s + "|" + s.length());
}
泛型类
public class Test10 {
public static void main(String[] args) {
GenericClassTest<String> gc = new GenericClassTest<String>();
gc.setE("哈哈");
// gc.setE(10);//设置一个数字会报错
String s = gc.getE();
System.out.println(s + "|" + s.length());
}
}
class GenericClassTest<E> {
private E e;
public E getE() {
return e;
}
public void setE(E e) {
this.e = e;
}
}
泛型接口
实现类确定泛型类型
// 1.实现类确定泛型类型
class GenericInterfaceImpl implements GenericInterface<String, Integer> {
@Override
public void test(String e) {
System.out.println(e);
}
@Override
public Integer add(Integer t) {
return t;
}
}
- 实现类不确定泛型,在调用的时候确定泛型
// 实现类不确定泛型
class GenericInterfaceImpl<E,T> implements GenericInterface<E, T> {
@Override
public void test(E e) {
System.out.println(e);
}
@Override
public T add(T t) {
return t;
}
}
// 在调用的时候确定泛型
GenericInterface<String, Double> gi = new GenericInterfaceImpl<String, Double>();
System.out.println(gi.add(2.5));
gi.test("hello");
- 匿名内部类确定泛型类型
GenericInterface<String, Boolean> gi = new GenericInterface<String, Boolean>(){
@Override
public void test(String e) {
System.out.println(e);
}
@Override
public Boolean add(Boolean t) {
return t;
}
};
泛型方法
概念: 把泛型定义在方法上,泛型方法又可以理解为局部泛型。
泛型方法的特点:
1. 泛型方法独立于泛型类或者泛型接口
2. 泛型方法在方法调用的时候确定类型
3. 一个泛型接口或者泛型类中可以有多个泛型方法
4. 一个泛型方法也可以定义多个泛型
public class GenericDemo04 {
public static void main(String[] args) {
GenericMethod<String, Integer> gm = new GenericMethod<String, Integer>();
// 2.泛型方法在方法调用的时候确定类型
gm.show(20.5);
Character c = gm.test('c');
System.out.println(c);
gm.method(25, 2.5);
}
}
class GenericMethod<E,H> {
private E e;
private H h;
// 1.泛型方法独立于泛型类或者泛型接口
public <T> void show(T t) {
System.out.println(t);
}
// 3.一个泛型接口或者泛型类中可以有多个泛型方法
public <K> K test(K K) {
return K;
}
// 4.一个泛型方法也可以定义多个泛型
public <V, U> void method(V v, U u) {
System.out.println(v);
System.out.println(u);
}
public E getE() {
return e;
}
public void setE(E e) {
this.e = e;
}
public H getH() {
return h;
}
public void setH(H h) {
this.h = h;
}
}
泛型限定符
概念: 用来限定泛型的符号
泛型限定符的常用格式:
1.?: 表示泛型可以是任意类型
2.? extends E:表示泛型可以是E或者E的子类
3. ? super E:表示泛型可以是E或者E的父类
public class GenericDemo05 {
public static void main(String[] args) {
// Object并不是代表任意类型
Collection<Object> c1 = new ArrayList<Object>();
// ?: 表示泛型可以是任意类型
Collection<?> c2 = new ArrayList<Object>();
Collection<?> c3 = new ArrayList<Fu>();
Collection<?> c4 = new ArrayList<Daughter>();
// ? `extends` E:表示泛型可以是E或者E的子类
Collection<? extends Fu> c5 = new ArrayList<Fu>();
Collection<? extends Fu> c6 = new ArrayList<Daughter>();
Collection<? extends Fu> c7 = new ArrayList<Son>();
// Collection<? extends Fu> c8 = new ArrayList<Object>(); 编译报错
// ? `super` E :表示泛型可以是E或者E的父类
Collection<? super Fu> c9 = new ArrayList<Fu>();
// Collection<? super Fu> c10 = new ArrayList<Daughter>(); 编译报错
// Collection<? super Fu> c11 = new ArrayList<Son>(); 编译报错
Collection<? super Fu> c12 = new ArrayList<Object>();
}
}
泛型嵌套
泛型嵌套:泛型中可以包含泛型
有以下常见几种情况:
- Collection嵌套Collection集合
- Collection嵌套Map集合
- Map嵌套Collection集合
- Map嵌套Map集合
public class GenericDemo06 {
public static void main(String[] args) {
// 存储: 由内到外添加到集合中
Collection<Student> class01 = new ArrayList<>();
class01.add(new Student("1001", "张三", 30));
class01.add(new Student("1002", "李四", 31));
class01.add(new Student("1003", "王五", 32));
Collection<Student> class02 = new ArrayList<>();
class02.add(new Student("1001", "张三", 30));
class02.add(new Student("1002", "李四", 31));
class02.add(new Student("1003", "王五", 32));
Collection<Student> class03 = new ArrayList<>();
class03.add(new Student("1001", "张三", 30));
class03.add(new Student("1002", "李四", 31));
class03.add(new Student("1003", "王五", 32));
Collection<Collection<Student>> school = new ArrayList<Collection<Student>>();
school.add(class01);
school.add(class02);
school.add(class03);
// 遍历: 由外到内
int index = 1;
for (Collection<Student> classList : school) {
System.out.println(index + "班");
for (Student s : classList) {
System.out.println("\t" + s);
}
index ++;
}
}
}