------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一,集合概念
之前我们存储大量的对象,可以使用数组:
但数组有两个缺陷:
1.其长度一旦确定,后期不能更改;对于元素的新增、删除就十分的不方便;
2.数组只能存储一种类型的数据。
为了解决上述问题,也为了我们程序员更加方便的存储大量的对象,Java为我们提供了一种"类":集合类;
1.集合:它的作用跟数组一样,就是存储大量对象的;
2.跟数组不同的:
1).使用集合可以是我们程序员不用关心"长度"的概念,"集合"对于我们来说,似乎像个"无底洞",可以存储无限数量的对象;
2).集合可以存储任何的"对象";(但后期我们也是经常会存储一种对象)
public class Demo {
public static void main(String[] args) {
//1.定义容器:集合类:ArrayList
ArrayList list = new ArrayList();
//2.实例化若干多的Student对象
for(int i = 0;i < 10000; i++){
//直接实例化,并向集合中添加对象(注意:这里添加的也是对象的引用)
list.add( new Student("姓名:" + i,i + 10));//姓名:0,10
}
//经过上述的第2步后,集合中添加了10000个Student对象的引用;
//3.遍历集合
for(int i = 0;i < list.size();i++){
//从集合中取出Student引用
Student s = (Student)list.get(i);//跟数组差不多,这里调用的是get()方法,获取一个Student的引用.由于get方法返回的是Object类型,所以这里强转一下
System.out.println(s.name + "," + s.age);
}
//假如,原集合存储的对象有增加,这时可以直接向集合中继续添加元素
for(int i = 10000;i < 20000; i++){
//直接实例化,并向集合中添加对象(注意:这里添加的也是对象的引用)
list.add( new Student("姓名:" + i,i + 10));//姓名:0,10
}
}
}
第二讲 Collection
一,Collection
1.它是所有List和Set集合的跟接口;
2.它内部定义了List和Set所应具有的方法;
学习:从Collection接口开始;
使用:从子类开始:ArrayList
Collection中定义的常用方法:
1.添加:
//大家以后看到某个方法的形参或返回值是E的话,那么就先把它视作:Object类型:
boolean add(Object e):向集合中添加元素;如果此 collection 由于调用而发生更改,则返回 true
boolean addAll(Collection c)
2.删除:
boolean remove(Object o):移除元素:此 collection 由于调用而发生更改),则返回 true 。
void clear():清空集合
boolean removeAll(Collection c)
3.判断:
boolean contains(Object o):判断参数在集合中是否存在;存在:返回true,否则返回false
boolean isEmpty():判断集合为空;
boolean containsAll(Collection c)
4.获取:
int size():获取集合内的元素的数量;
boolean retainAll(Collection c)
二,Collection中的一些批量操作 的方法:
添加
boolean addAll(Collection c):指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
删除
boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
判断:
boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的"所有元素",则返回 true。
boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。
代码:
import java.util.ArrayList;
import java.util.Collection;
public class CollectionMethod {
public static void main(String[] args) {
methodSingle();
System.out.println("====================");
methodAll();
}
public static void methodSingle(){
//使用子类ArrayList
Collection list = new ArrayList();
//向集合中添加引用(这里添加字符串)
list.add("刘若英");
list.add("刘德华");
list.add("刘诗诗");
list.add("刘惜君");
//打印集合:
System.out.println("原集合:" + list);
//测试:remove(Object o);
System.out.println("移除刘若英:" + list.remove("刘若英"));//true
System.out.println("移除后:" + list);
//4.void clear():清空集合
/*list.clear();
System.out.println("集合被清空了:" + list);*/
//5.boolean contains(Object o):判断参数在集合中是否存在;存在:返回true,否则返回false
System.out.println("判断刘若英是否存在:" + list.contains("刘若英"));
System.out.println("判断刘德华是否存在:" + list.contains("刘德华"));
//6.boolean isEmpty():判断集合为空;
/*System.out.println("集合是否为空:" + list.isEmpty());
list.clear();
System.out.println("清空后,判断是否为空:" + list.isEmpty());*/
//7.int size():获取集合内的元素的数量;
System.out.println("集合内元素的数量:" + list.size());
}
public static void methodAll(){
//集合1
Collection list1 = new ArrayList();
list1.add("刘若英");
list1.add("刘德华");
list1.add("刘诗诗");
list1.add("刘惜君");
//集合2
Collection list2 = new ArrayList();
list2.add("王心凌");
list2.add("王力宏");
list2.add("王光良");
list2.add("王菲");
//addAll()
list1.addAll(list2);//合班
System.out.println("合班之后list1中的元素:" + list1);
System.out.println("list2中的元素:" + list2);
//removeAll();
/* list1.removeAll(list2);//再分班
System.out.println("分班后,list1中的元素:" + list1);
System.out.println("list2中的元素:" + list2);
*/
//containsAll
System.out.println("list1中包含list2中的所有元素吗?" + list1.containsAll(list2));
Collection list3 = new ArrayList();
list3.add("毛爷爷");
list3.add("铁娘子");
list3.add("奥巴马");
list3.add("金正恩");
System.out.println("list1中包含list3中的所有元素吗?" + list1.containsAll(list3));
//retainAll()
list2.retainAll(list3);
System.out.println("移除list2中未包含在list3中的所有元素:" + list2);
System.out.println("list2中的元素;" + list2);
System.out.println("list3中的元素:" + list3);
Collection list4 = new ArrayList();
list4.add("aa");
list4.add("bb");
Collection list5 = new ArrayList();
list5.add("cc");
list5.add("dd");
list4.retainAll(list5);
System.out.println("list4 中的所有元素:" + list4);
System.out.println("list5 中的所有元素:" + list5);
}
}
三,迭代器:java.util.Iterator(接口)
成员方法:
1.boolean hasNext():判断是否可以返回下一个元素;
2.Object next():返回下一个元素;
两种遍历方式:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
*
*
*
*/
public class CollectionTraverse {
public static void main(String[] args) {
methodTraverseFirst();
System.out.println("===========");
methodTraverseSecond();
}
/*
* 方法一:
*
*/
public static void methodTraverseFirst() {
//实例化一个集合
Collection list = new ArrayList();
//填充集合
list.add("王心凌");
list.add("张韶涵");
list.add("辛晓琪");
list.add("蔡依林");
//获取数组
Object[] objArray = list.toArray();
//遍历数组
for(int i = 0;i < objArray.length ; i++){
//由于toArray()方法返回的是Object类型的数组,而我们存储的是String对象。可以将Object强制转换为String
String s =(String) objArray[i];
System.out.println("数组:"+s);
}
}
public static void methodTraverseSecond(){
//1.实例化一个集合
Collection list = new ArrayList();
//2.填充集合
list.add("王心凌");
list.add("张韶涵");
list.add("辛晓琪");
list.add("蔡依林");
//3.使用迭代器遍历:
Iterator it = list.iterator();
while(it.hasNext()){
Object o = it.next();
System.out.println("Iterator:" + o);
}
}
}
第三讲 List
一,层次
Collection(接口):
|--List(接口):
|--ArrayList(类)
二,List接口的特点:
1.有序的;
2.可以根据整数的索引访问元素(类似于数组的使用);
3.允许重复的元素;
三,List接口中的特有方法:
void add(int index,Object element):在index的位置上插入元素element,原索引上的元素依次后移;
Object remove(int index):移除列表中指定位置的元素(可选操作)。将所有的后续元素向左移动(将其索引减 1)。返回从列表中移除的元素。
Object get(int index):取index位置上的元素。(它就类似于数组的下标)
Object set(int index,E element):将element替换原index位置上的元素;
LitsIterator listIterator():List接口特有的Iterator(),同样是用来遍历元素的。
四,|--List接口:
|--ArrayList类:内部数组实现;线程不安全的。效率高
|--Vector类:内部数组实现;线程安全的。效率低;
|--LinkedList类:链表实现:线程不安全的。效率高;
五,Iterator接口:是单向的,只能向下遍历;
|--ListIterator接口:
|--特有的方法:
hasPrevious():如果可以向上遍历,返回true
previous():获取前一个元素;
import java.util.ArrayList;
import java.util.List;
public class ListMethod {
public static void main(String[] args) {
//实例化一个集合
List list = new ArrayList();
//先使用Collection的add添加一些元素
list.add("紫薇");
list.add("尔康");
list.add("五阿哥");
//1.void add(int index,Object element)
//在ccc前面加一个XXX
list.add(2,"小燕子");
System.out.println("add方法之后的集合:" + list);
list.add(3,"漱芳斋");//OK的
System.out.println("add方法之后的集合:" + list);
//2.Object remove(int index):
list.remove(3);
System.out.println("移除掉之后的元素:" + list);
//3.Object get(int index)
System.out.println("获取索引为3的元素:" + list.get(3));
//4.Object set(int index,E element)
//将XXX改为YYY
list.set(3, "皇阿玛");
System.out.println("替换后为:" + list);
}
}1
六,Collection(接口)
|--List(接口):特点:1.有序的;2.可以存储重复元素;
|--ArrayList:
1.数组实现:
2.线程不安全,效率高;
|--Vector:
1.数组实现:
2.线程安全,效率低;
|--LinkedList:
1.链表:
2.线程不安全的,效率高;
七,Collection(接口)
|--List(接口):
|--Vector(类):
1.数组实现。查询快,增删慢;
2.线程安全,效率低;
Vector是List的子类,所以:它具有List和Collection的所有功能;
另外Vector又增加了一些特有的功能:
public void addElement(Object obj):向集合添加一个obj,添加到集合的末尾;
public Object elementAt(int index):获取index位置上的元素;作用等同于:List-->get(int index);
public Enumeration elements():返回一个枚举;
八,LinkedList的特有方法:
public void addFirst(E e)及addLast(E e)
public E getFirst()及getLast()
public E removeFirst()及public E removeLast()
如果将LinkeList作为链表使用:
1.使用addFirst()进行添加;
使用get(int index)进行获取;
2.使用addFirst()进行添加;
使用getFirst()获取;
使用removeFirst()移除第一个元素;
3.使用add(Object o)进行添加;
使用getLast()进行获取
使用removeLast()移除最后的元素;
如果将LinkedList作为普通的集合使用:
1.使用add()添加;
2.使用get()获取;
第四讲 泛型
一,泛型概念
1.集合就像仓库,可以装任何的引用类型;因为它的add()方法接收的是Object类型的。
2.对于集合类,看似功能比较强大,可以添加任何类型的引用。
但取出的时候,也比较费事,
3.我们以后使用集合类,经常是向集合中添加一种类型的引用;
4.这时,Java为我们提供了一种语法功能:可以将一个集合,在定义时,同时定义这个集合中只能存放
什么类型的元素。这种功能就叫:泛型;
5.例如:我们需要定义一个只存储"字符串"的集合
ArrayList<String> list = new ArrayList<String>();
或
ArrayList<String> list = new ArrayList<>();(我会经常使用这种形式)
或
ArrayList<String> list = new ArrayList();
6.通过JAD查看反编译的class文件,我们发现,泛型的信息已经没有了。
所以:泛型只是在编译期所具有的一种行为,这种行为能够规范一个集合内只能存储我们定义的某种类型。
如果向集合中存储其它类型,编译器会产生编译错误。
7.泛型可以定义泛型类,泛型方法,泛型接口
二,泛型的通配符
1.<?>:
1).这种变量可以指向什么样的对象:具有任何泛型的集合。
2).这种集合可以存储什么类型的数据:什么都不能存;
3).这种集合获取时,可以用什么类型接收:只能用Object。因为使用了?,所以不确定里面存了什么类型;
作用:这种声明的引用,只能获取,不能存入。它一般用于"方法的返回值"的声明;
2.<? extends E>:
1).这种变量可以指向什么样的对象:此声明的集合意味着此变量只能指向具有E或E的子类泛型的集合对象;
2).这种集合可以存储什么类型的数据:因为某个具体的子类不确定,所以什么类型的对象都不能存;
3).这种集合获取时,可以用什么类型接收:使用E及E的父类类型接收都可以;
作用:这种声明的引用,只能获取,不能存入。它一般也是用于"方法的返回值"声明;
3.<? super E>:
1).这种变量可以指向什么样的对象:任何具有E及E的父类类型泛型的集合对象;
2).这种集合可以存储什么类型的数据:任何的E及E的子类类型都可以;
3).这种集合获取时,可以用什么类型接收:取出时只能用Object接收。
作用:这种声明的引用,可以存入元素,但不能用除Object外的其它类型接收。这种声明的格式一般用在"方法的形参"
第五讲 增强for循环
一,格式:for(数据类型 变量名 : 集合对象名/数组名)
1.增强for不使用循环变量;
2.根据自己的需要,如果需要使用循环变量,那么就使用普通的for循环;
如果不需要循环变量,只是简单的遍历一下集合或数组,那么使用增强for的语法会简洁许多。
3.增强for类似于迭代器,通过它对集合进行遍历时,仍然不能使用集合对象对集合内部进行修改,否则将抛出:并发修改异常:java.util.ConcurrentModificationException
第六讲 Set(接口)
一,Collection(接口):
|--List(接口):有序的,可以存储重复值;
|--ArrayList(类):
|--Vector(类):
|--LinkedList(类):
|--Set(接口):无序的(取出时跟存入的顺序不一致)。不能存储重复值
它没有新增任何方法,我们使用Collection中的方法就可以操作Set集合了。
|--HashSet(子类):
注意:Set保证唯一性的方式:先判断hashCode,如果hashCode一致再判断equals()
二,LinkedHashSet类
特点:
1.由链表保证:有序(取出时跟存入的顺序一致);
2.由哈希表保证元素唯一:
它没有特有的成员,都是继承下来的。
三,TreeSet类
1.内部使用"树"结构:
2."树"结构,存储数据的特点:将数据进行排序:
这种排序会先进行比较,比较有两种方式
使用TreeSet存储元素,要求元素必须具有"比较的功能"
我们怎么才能具有比较的功能:
方式一:将我们的类实现:Comparable接口,重写compareTo()-->自然排序;
方式二:我们的类不用实现任何接口,在实例化TreeSet时,给TreeSet传递一个"比较器对象",这个比较器
对象一定要是:实现Comparator接口,重写compare()方法
第七讲 List接口和Set接口的小结
一,Collection:
|--List:有序的;可以存储重复值;
|--ArrayList:数组实现。线程不安全的,效率高;
|--Vector:数组实现。线程安全,效率低;
|--LinkedList:链表实现。线程不安全,效率高;
|--Set:无序的;不能存储重复值;
|--HashSet:哈希表实现。线程不安全的,效率高;
判断重复元素:
利用元素对象的:hashCode()和equals()
两个方法如果都返回true,那么就认为是重复元素,不存储;
|--LinkedHashSet:链表和哈希表实现。线程不安全的,效率高;
利用链表保证"有序";
利用哈希表保证"唯一";
|--TreeSet:二叉树实现。线程不安全,效率高;
可对元素排序。判断重复元素,以及对元素排序的方式:
1.自然排序:我们自定义的类必须实现Comparable接口
重写里面的compareTo()方法;
2.比较器:我们的类不需要实现任何接口。
在实例化TreeSet时,要为TreeSet传递一个比较器对象,这个对象必须实现Comparator接口
重写里面compare()方法;
--比较器优先
第八讲 Map接口
一,1.Map接口跟Collection接口没有关系:
2.Map接口是一个单独的接口,它使用另外的同Collection完全不同的方式存储、管理数据;
3.Map集合存储元素的特点:使用"键值对";
4.之前我们使用Collection集合,存入时,就是简单的向集合中存储;
取出时:使用数组、迭代器、List集合中增加了一个带"索引"的
5.有时候,我们存储一个对象,会给它"起个名字",获取对象时,用这个名字就可以取出这个对象。
这时候,对于我们取出对象,非常的方便;
6.使用Map存储对象:存储时,要给对象起个名字,存入时,连名字和对象一起存储。
名字:键(key) 要存储的对象:值(Value);
二,Map接口的基本方法:
1.添加:
V put(K key,V value):向集合中添加元素;如果存储相同的键,不同的值,新值会替换旧值,键不变;
2.删除:
V remove(Object key):根据某个"键",删除元素;返回被删除的Value
void clear():清空集合;
3.判断:
boolean containsKey(Object key):集合是否包含键key,包含返回true,否则返回false
boolean containsValue(Object value):集合是否包含值value,包含返回true,否则返回false
boolean isEmpty():判断集合是否为空。
4.获取
int size()
V get(Object key)
Set<K> keySet()
Collection<V> values()
Set<Map.Entry<K,V>> entrySet()
三,LinkedHashMap类
1.内部使用链表结构,和哈希表结构;
2.此Map是有序的;
四,TreeMap类:
1.内部使用红黑树结构;
2.树结构会对内部的"键"进行排序:
1).自然排序:类要实现Comparable接口,重写compareTo()
2).比较器排序:类要实现Comparator接口,重写compare()方法;
第九讲 Collections工具类
一,此类没有提供能使用的构造方法,内部包含了大量对Collection集合进行操作的一些"静态方法";
public static <T> void sort(List<T> list):根据元素的自然顺序 对指定列表按升序进行排序。
public static <T> int binarySearch(List<?> list,T key):在集合list中查找key,使用二分查找:
参数说明:
list - 要搜索的列表。
key - 要搜索的键。
public static <T> T max(Collection<?> coll):根据元素的自然顺序,返回给定 collection 的最大元素。
public static void reverse(List<?> list):反转指定列表中元素的顺序。
public static void shuffle(List<?> list):将内部的元素随机打乱