一、单列集合
1.单列集合体系
Collection
List Set
ArrayList LinkedList HashSet LinkedHashSet
List :存取有序、有索引、还可以存储重复的元素 ArrayList:底层是数组实现的,有索引,查询快、增删慢 LinkedList:底层是链表实现的,有索引,查询慢、增删快 Set : 存取无序、没有索引、不可以存储重复的元素 HashSet:底层是哈希表+红黑树的,存取无序、没有索引、不可以存储重复的元素 LinkedHashSet:底层是链表+哈希表实现的,可以保证存取顺序,没有索引、不可以存储重复的元素 2.Collection接口中的共性的功能
boolean add(E e); 向集合中添加元素 void clear(); 清空集合所有的元素 boolean remove(E e); 删除指定的元素 boolean contains(E e); 判断集合中是否包含传入的元素 boolean isEmpty(); 判断集合是否为空 int size(); 获取集合的长度 Object[] toArray(); 将集合转成数组 示例代码: public class Demo01Collection { public static void main(String[] args) { //创建集合对象,可以使用多态 //Collection<String> coll = new ArrayList<>(); Collection<String> coll = new HashSet<>(); System.out.println(coll);//重写了toString方法 [] /* public boolean add(E e): 把给定的对象添加到当前集合中 。 返回值是一个boolean值,一般都返回true,所以可以不用接收 */ boolean b1 = coll.add("张三"); System.out.println("b1:"+b1);//b1:true System.out.println(coll);//[张三] coll.add("李四"); coll.add("李四"); coll.add("赵六"); coll.add("田七"); System.out.println(coll);//[张三, 李四, 赵六, 田七] /* public boolean remove(E e): 把给定的对象在当前集合中删除。 返回值是一个boolean值,集合中存在元素,删除元素,返回true 集合中不存在元素,删除失败,返回false */ boolean b2 = coll.remove("赵六"); System.out.println("b2:"+b2);//b2:true boolean b3 = coll.remove("赵四"); System.out.println("b3:"+b3);//b3:false System.out.println(coll);//[张三, 李四, 田七] /* public boolean contains(E e): 判断当前集合中是否包含给定的对象。 包含返回true 不包含返回false */ boolean b4 = coll.contains("李四"); System.out.println("b4:"+b4);//b4:true boolean b5 = coll.contains("赵四"); System.out.println("b5:"+b5);//b5:false //public boolean isEmpty(): 判断当前集合是否为空。 集合为空返回true,集合不为空返回false boolean b6 = coll.isEmpty(); System.out.println("b6:"+b6);//b6:false //public int size(): 返回集合中元素的个数。 int size = coll.size(); System.out.println("size:"+size);//size:3 //public Object[] toArray(): 把集合中的元素,存储到数组中。 Object[] arr = coll.toArray(); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } //public void clear() :清空集合中所有的元素。但是不删除集合,集合还存在 coll.clear(); System.out.println(coll);//[] System.out.println(coll.isEmpty());//true } }
二、迭代器
1.Iterator接口
作用:通用的对于集合的遍历形式
获取迭代器对象的方式:Iterator<> it = 集合对象.iterator();
2.常用方法:
boolean hashNext(); 判断迭代器中是否有元素
E next(); 获取元素
void remove(); 删除元素
3.示例代码
public class Demo01Iterator { public static void main(String[] args) { //创建一个集合对象 Collection<String> coll = new ArrayList<>(); //往集合中添加元素 coll.add("姚明"); coll.add("科比"); coll.add("麦迪"); coll.add("詹姆斯"); coll.add("艾弗森"); /* 1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态) 注意: Iterator<E>接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型 */ //多态 接口 实现类对象 Iterator<String> it = coll.iterator(); /* 发现使用迭代器取出集合中元素的代码,是一个重复的过程 所以我们可以使用循环优化 不知道集合中有多少元素,使用while循环 循环结束的条件,hasNext方法返回false */ while(it.hasNext()){ String e = it.next(); System.out.println(e); } } }
4.使用迭代器对集合元素进行操作
/* 迭代器的使用注意事项: next()方法每调用一次都会将指针向后移动一位 在使用迭代器进行遍历的时候,如果向集合中添加元素。那么会出现并发修改异常 解决方式: 使用List集合特有的迭代器对象:ListIterator */ public class Demo01 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("苍老师"); list.add("小泽老师"); list.add("波多老师"); list.add("风间老师"); //使用迭代器遍历集合 //Iterator<String> it = list.iterator(); ListIterator<String> it = list.listIterator(); while(it.hasNext()) { String name = it.next(); if(name.equals("波多老师")) { //it.remove(); 可以删除成功 //list.remove(name); 可以删除成功 //list.add("东尼老师"); // 并发修改异常 ConcurrentModificationException it.add("东尼老师"); } } System.out.println(list); } }
三、增强for循环
1.定义格式
for(容器的数据类型 变量名 : 容器对象) {
循环体;
}
2.示例代码
四、泛型
1.自己定义一个泛型类
“
//带有泛型的类 public class GenericClass<E> { private E name; public E getName() { return name; } public void setName(E name) { this.name = name; } } //测试类 public class Demo02GenericClass { public static void main(String[] args) { //不写泛型默认为Object类型 GenericClass gc = new GenericClass(); gc.setName("只能是字符串"); Object obj = gc.getName(); //创建GenericClass对象,泛型使用Integer类型 GenericClass<Integer> gc2 = new GenericClass<>(); gc2.setName(1); Integer name = gc2.getName(); System.out.println(name); //创建GenericClass对象,泛型使用String类型 GenericClass<String> gc3 = new GenericClass<>(); gc3.setName("小明"); String name1 = gc3.getName(); System.out.println(name1); } }
2.自己定义一个泛型方法
//带有泛型方法的类 public class GenericMethod { //定义一个含有泛型的方法 public <M> void method01(M m){ System.out.println(m); } //定义一个含有泛型的静态方法 public static <S> void method02(S s){ System.out.println(s); } } //测试类 public class Demo03GenericMethod { public static void main(String[] args) { //创建GenericMethod对象 GenericMethod gm = new GenericMethod(); /* 调用含有泛型的方法method01 传递什么类型,泛型就是什么类型 */ gm.method01(10); gm.method01("abc"); gm.method01(8.8); gm.method01(true); gm.method02("静态方法,不建议创建对象使用"); //静态方法,通过类名.方法名(参数)可以直接使用 GenericMethod.method02("静态方法"); GenericMethod.method02(1); } }
3.自定义一个带有泛型的接口
//带有泛型的接口 public interface GenericInterface<I> { public abstract void method(I i); } //第一种实现类的方式 public class GenericInterfaceImpl1 implements GenericInterface<String>{ @Override public void method(String s) { System.out.println(s); } } //第二种实现类的方式 public class GenericInterfaceImpl2<I> implements GenericInterface<I> { @Override public void method(I i) { System.out.println(i); } } //测试类 public class Demo04GenericInterface { public static void main(String[] args) { //创建GenericInterfaceImpl1对象 GenericInterfaceImpl1 gi1 = new GenericInterfaceImpl1(); gi1.method("字符串"); //创建GenericInterfaceImpl2对象 GenericInterfaceImpl2<Integer> gi2 = new GenericInterfaceImpl2<>(); gi2.method(10); GenericInterfaceImpl2<Double> gi3 = new GenericInterfaceImpl2<>(); gi3.method(8.8); } }
4.泛型的通配符 通配符:?
public class Demo05Generic { public static void main(String[] args) { ArrayList<Integer> list01 = new ArrayList<>(); list01.add(1); list01.add(2); ArrayList<String> list02 = new ArrayList<>(); list02.add("a"); list02.add("b"); printArray(list01); printArray(list02); //ArrayList<?> list03 = new ArrayList<?>(); } /* 定义一个方法,能遍历所有类型的ArrayList集合 这时候我们不知道ArrayList集合使用什么数据类型,可以泛型的通配符?来接收数据类型 注意: 泛型没有继承概念的 */ public static void printArray(ArrayList<?> list){ //使用迭代器遍历集合 Iterator<?> it = list.iterator(); while(it.hasNext()){ //it.next()方法,取出的元素是Object,可以接收任意的数据类型 Object o = it.next(); System.out.println(o); } } }
上下限定: ? extends E 只能传递的是E这个类型本身或者是E类型的子类 ? super E 只能传递的是E这个类型本身或者是E类型的父类 示例代码:
public class Demo06Generic { public static void main(String[] args) { Collection<Integer> list1 = new ArrayList<Integer>(); Collection<String> list2 = new ArrayList<String>(); Collection<Number> list3 = new ArrayList<Number>(); Collection<Object> list4 = new ArrayList<Object>(); getElement1(list1); //getElement1(list2);//报错 getElement1(list3); //getElement1(list4);//报错 //getElement2(list1);//报错 //getElement2(list2);//报错 getElement2(list3); getElement2(list4); /* 类与类之间的继承关系 Integer extends Number extends Object String extends Object */ } // 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类 public static void getElement1(Collection<? extends Number> coll){} // 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类 public static void getElement2(Collection<? super Number> coll){} }
五、案例
1.将偶数放在集合的左边,将奇数放在集合的右边
/* 定义一个集合,存储1-10的数字 将集合中偶数元素放到左边,奇数元素放到右边。(不能创建其他集合) 例如: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [2, 4, 6, 8, 10, 3, 7, 1, 9, 5] */ public class Test01 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); for (int i = 1; i <= 10; i++) { list.add(i); } System.out.println(list); int index = 0; //遍历集合,拿到每一个数字 for (int i = 0; i < list.size(); i++) { int num1 = list.get(i); int num2 = list.get(index); if(num1 % 2 == 0) { list.set(i,num2); list.set(index,num1); index++; } } System.out.println(list); } }
2.随机双色球生成器
public class Test02 { public static void main(String[] args) { //保存购买的号码 ArrayList<String> list = new ArrayList<>(); list.add("8 12 23 25 26 31 8"); list.add("6 11 24 27 30 32 10"); list.add("4 7 12 16 19 22 12"); list.add("9 13 16 25 27 29 4"); while(true) { ArrayList<Integer> red = new ArrayList<>(); Random r = new Random(); while(red.size() != 6) { int num = r.nextInt(33)+1; if(!red.contains(num)) { red.add(num); } } Collections.sort(red); int blue = r.nextInt(16)+1; String s = ""; for(int i : red) { s += i; s += " "; } s += blue; if(!list.contains(s)) { System.out.println(s); break; } } } }