一、概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
二、和数组的区别:
(1)数组长度固定,集合长度不固定。
(2)数组可以存储基本类型 和引用类型,而集合只能存储引用类型。
三、位置
java.util.*;
Collection
体系集合
-
特点:代表一组任意类型的对象,无序、无下标、不能重复。
-
方法:
-
boolean add(Object obj)//添加一个对象。
-
boolean addAll(Collection c)//将一个集合中的所有对象添加到此集合中。
-
void clear()//清空此集合中的所有对象。
-
boolean contains(Object o)//检查此集合中是否包含o对象.
-
boolean equals(Object o)//比较此集合是否与指定对象相等。.
-
boolean isEmpty()//判断此集合是否为空
-
boolean remove(0bject o)//在此集合中移除o对象.
-
int size()//返回此集合中的元素个数。
-
0bject[] toArray()//将此集合转换成数组。
-
public class CollectionTest {
public static void main(String[] args) {
Collection collection = new ArrayList();
// 添加元素
collection.add("鼠牛虎兔");
collection.add("龙蛇马羊");
collection.add("猴鸡狗猪");
System.out.println("集合个数:"+collection.size());
System.out.println(collection);
//删除元素
// collection.remove("龙蛇马羊");
//System.out.println(collection);
//collection.clear();
//System.out.println(collection);
//遍历集合使用加强for循环
for (Object i : collection) {
System.out.println(i);
}
//迭代器Iterator
/*
hasNext();有没有下一个元素
next();获取下一个元素
remove();删除当前元素
*/
Iterator iterator = collection.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
//collection.remove(next);//java.util.ConcurrentModificationException并发修改异常
//在迭代器里不能使用collection的方法修改
// iterator.remove(); 可以用这个方法
}
System.out.println("当前集合内元素个数:"+collection.size());
//判断
Boolean b = collection.contains("龙蛇马羊");
System.out.println(b);
System.out.println(collection.isEmpty());
}
}
集合个数:3
[鼠牛虎兔, 龙蛇马羊, 猴鸡狗猪]
鼠牛虎兔
龙蛇马羊
猴鸡狗猪
鼠牛虎兔
龙蛇马羊
猴鸡狗猪
当前集合内元素个数:3
true
false
public class CollectionTest01 {
public static void main(String[] args) {
Collection collection = new ArrayList();
Student student1 = new Student("lily",20);
Student student2 = new Student("张飞",28);
Student student3 = new Student("关羽",29);
Student student4 = new Student("刘备",31);
//添加元素
collection.add(student1);
collection.add(student2);
collection.add(student3);
collection.add(student4);
System.out.println("集合大小:"+collection.size()+"内容:"+collection.toString());
//删除元素
collection.remove(student1);
System.out.println(collection.toString());
//遍历
for (Object ob : collection) {
Student s = (Student) ob;
System.out.println(s.toString());
}
System.out.println("===================");
//迭代器方法
Iterator iterator = collection.iterator();
while (iterator.hasNext()){
Student s = (Student) iterator.next();
System.out.println(s.toString());
}
}
}
集合大小:4内容:[Student [name =lily,age =20], Student [name =张飞,age =28], Student [name =关羽,age =29], Student [name =刘备,age =31]]
[Student [name =张飞,age =28], Student [name =关羽,age =29], Student [name =刘备,age =31]]
Student [name =张飞,age =28]
Student [name =关羽,age =29]
Student [name =刘备,age =31]
===================
Student [name =张飞,age =28]
Student [name =关羽,age =29]
Student [name =刘备,age =31]
List集合
List子接口
特点:有序、有下标、元素可以重复
方法:
-
void add(int index, Object o) //在index位置插入对象o。
-
boolean addAll(int index, Collection c) //将 - -个集合中的元素添加到此集合中的index位置。
-
0bject get(int index) //返 回集合中指定位置的元素。
-
List subList(int fromIndex, int LoIndex) //返回fromIndex和toIndex之间的集合元素。<E>:list迭代器 可以从前到后,也可以从后前。
/**
* List子接口的使用
* 特点:有序、有下标、可以重复
*/
public class ListTest {
public static void main(String[] args) {
List list = new ArrayList<>();//先创建集合对象
//1.添加元素
list.add("刘备");
list.add("关羽");
list.add("张飞");
list.add("赵云");
list.add("马超");
list.add("黄忠");
list.add(0,"姚老大");//在指定位置添加元素
System.out.println(list.toString());
//2。删除元素
list.remove(0);
System.out.println("删除之后还有"+list.toString());
//3.遍历
//for遍历
System.out.println("==========for遍历=============");
for (int i = 0; i < list.size() ; i++) {
System.out.println(list.get(i));
}
//增强for
System.out.println("==========增强for遍历=============");
for (Object object : list) {
System.out.println(object);
}
//使用迭代器
System.out.println("==========使用迭代器=============");
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//使用List迭代器
ListIterator listIterator = list.listIterator();//允许程序员以任意方向遍历列表,previous(),next()
System.out.println("==========使用迭代器从前向后遍历==============");
while (listIterator.hasNext()){
System.out.println(listIterator.nextIndex());
System.out.println(listIterator.next());
}
System.out.println("==========使用迭代器从后向前遍历==============");
while (listIterator.hasPrevious()){
System.out.println(listIterator.previousIndex());
System.out.println(listIterator.previous());
}
//4.判断
System.out.println(list.contains("马超"));
System.out.println(list.isEmpty());
//5.获取位置
System.out.println(list.indexOf("赵云"));
}
}
public class ListTest01 {
public static void main(String[] args) {
List list = new ArrayList();
//1.增加元素
list.add(404);
list.add(985);
list.add(211);
list.add(865);
System.out.println("元素个数: "+list.size());
System.out.println(list.toString());
//2.删除元素
//list.remove(404);//java.lang.IndexOutOfBoundsException: Index: 404, Size: 4
list.remove((Integer)404);
System.out.println("元素个数: "+list.size());
System.out.println(list.toString());
//subList:返回子集合,含头不含尾
List sublist = list.subList(0,2);
System.out.println(sublist.toString());
}
}
List实现类
ArrayList(重点)
-
数据结构实现,查询快、增删慢。
-
JDK1.2版本,运行效率快、线程不安全。
/**
* ArrayList的使用
*/
public class ArrayListTest {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList<>();
//增加
Student student1 = new Student("李白",18);
Student student2 = new Student("杜甫",19);
Student student3 = new Student("苏轼",40);
Student student4 = new Student("苏辙",20);
arrayList.add(student1);
arrayList.add(student2);
arrayList.add(student3);
arrayList.add(student4);
System.out.println("元素个数:"+arrayList.size());
System.out.println("元素为: "+arrayList.toString());
//删除
arrayList.remove(student2);
arrayList.remove(new Student("李白",18));//要实现这个要重写equals方法
System.out.println("元素个数:"+arrayList.size());
System.out.println("元素为: "+arrayList.toString());
//遍历
//略
//判断
System.out.println(arrayList.contains(student3));
System.out.println(arrayList.isEmpty());
//查找
System.out.println(arrayList.indexOf(student4));
}
}
重写equals方法:
@Override
public boolean equals(Object obj) {
//1.是否为同一对象
if (this==obj) {
return true;
}
//2.判断是否为空
if (obj==null) {
return false;
}
//3.判断是否是Student类型
if (obj instanceof Student) {
Student student=(Student) obj;
//4.比较属性
if(this.name.equals(student.getName())&&this.age==student.age) {
return true;
}
}
//不满足,返回false
return false;
}
源码分析
ArrayList:默认容量10 DEFAULT_CAPACITY=10;
注意:如果没有向集合中添加任何元素时,容量为0.
elementData存放元素的数组
size 实际元素个数
add()添加元素
每次扩容大小,为原来的1.5倍
Vector:(枚举)
-
数据结构实现,查询快、增删慢;
-
JDK1.0版本,运行效率慢、线程安全。
/**
* Vector集合的使用
* 数据结构:数组
*/
public class VectorTest {
public static void main(String[] args) {
Vector vector = new Vector<>();
//1.添加元素
vector.add("葡萄");
vector.add("樱桃");
vector.add("橘子");
vector.add("橙子");
vector.add("猕猴桃");
vector.add("梨子");
System.out.println("Vecto集合大小: "+vector.size());
System.out.println("Vector内容为: "+vector.toString());
//2.删除
vector.remove(5);
vector.remove("橙子");
//vector.clear();清空集合
System.out.println("Vecto集合大小: "+vector.size());
System.out.println("Vector内容为: "+vector.toString());
//3.遍历
//使用枚举器
Enumeration elements = vector.elements();
while (elements.hasMoreElements()){
String o = (String) elements.nextElement();
System.out.println(o);
}
//4.判断
System.out.println(vector.contains("橘子"));
System.out.println(vector.isEmpty());
//5.其他方法 firstElement、lastElement、elementAt
System.out.println(vector.firstElement());
System.out.println(vector.lastElement());
}
}
LinkedList:
-
链表结构实现。增删快,查询慢
/**
* LinkedList集合的使用
* 双向链表,增删快,查询慢
*/
public class LinkedListTest {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
//增加
Student student1 = new Student("李白",18);
Student student2 = new Student("杜甫",19);
Student student3 = new Student("苏轼",40);
Student student4 = new Student("苏辙",20);
linkedList.add(student1);
linkedList.add(student2);
linkedList.add(student3);
linkedList.add(student4);
System.out.println("元素个数:"+linkedList.size());
System.out.println("元素为: "+linkedList.toString());
//删除
linkedList.remove(student2);
linkedList.remove(new Student("李白",18));//要实现这个要重写equals方法
System.out.println("元素个数:"+linkedList.size());
System.out.println("元素为: "+linkedList.toString());
//遍历
//略
//判断
System.out.println(linkedList.contains(student3));
System.out.println(linkedList.isEmpty());
//查找
System.out.println(linkedList.indexOf(student4));
}
}
泛型
java泛型是JDK1.5引入的新特性,其本质是参数化类型,把类型作为参数传递。
-
常用形式有泛型类、泛型接口、泛型方法。
-
语法:
-
<T,...> T称为类型占位符,表示引用类型
-
-
好处:
-
(1)提高代码重用性
-
(2)防止类型转换异常,提高代码安全性。
-
-
泛型类:
/*** * 泛型类 * 语法:类名<T> * T是类型占位符,只能是引用类型,如果编写多个,使用逗号隔开 */ public class MyGeneric <T> { //使用泛型T //1.创建变量 T t; //2.泛型作为方法的参数 public void show(T t){ System.out.println(t); } //3.泛型作为方法的返回值 public T getT(){ return t; } }
MyGeneric<String> myGeneric = new MyGeneric<>(); myGeneric.t = "hello"; myGeneric.show("加油,奥利给!"); String string = myGeneric.getT(); System.out.println(string); MyGeneric<Integer> myGeneric1 = new MyGeneric<>(); myGeneric1.t = 404; myGeneric1.show(9852); Integer integer = myGeneric1.getT(); System.out.println(integer);
-
泛型接口:
/** * 泛型接口 * 语法:接口名<T> * 注意:不能使用泛型静态常量 * */ public interface GenericInterface <T> { String name = "法外狂徒"; T server(T t); }
public class GenericInterfaceImpl implements GenericInterface<String> { @Override public String server(String s) { System.out.println(s); return s; } }
//泛型接口 System.out.println("==========泛型接口=============="); GenericInterfaceImpl impl = new GenericInterfaceImpl(); impl.server("就你叫法外狂徒呀?!"); //System.out.println(impl.name); GenericInterfaceImpl1<Integer> impl1 = new GenericInterfaceImpl1<>(); impl1.server(1080);
-
泛型方法:
/** * 泛型方法 * 语法:<T> 返回值类型(与之前写的方法有些不太一样) */ public class GenericMethod { //泛型方法 public <T> T show(T t){ T t1; System.out.println("泛型方法"+t); return t; } } //调用泛型方法 System.out.println("=============泛型方法============"); GenericMethod genericMethod = new GenericMethod(); genericMethod.show("法网恢恢"); genericMethod.show(521); genericMethod.show(9.4);
泛型集合
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
特点:
-
编译时即可检查,而非运行时抛出异常。
-
访问时,不同类型转换(拆箱)。
-
不同泛型之间引用不能相互赋值,泛型不存在多态。
Set集合
set子接口
特点:无序、无下标、元素不可重复。
方法:全部继承自Collection中的方法。
HashSet[重点] :
-
基于HashCode实现元素不重复。
-
当存入元素的哈希码相同时,会调用equals进行确认,如结果为true, 则拒绝后者存入
/**
* HashSet的使用
* 存储结构:哈希表(数组+链表+红黑树)
* (1)根据hashCode计算保存位置,如果此位置为空,则直接保存,否则执行下一步
* (2)在执行equals方法,如果equals认为两者相同,结果为true,则认为是重复,不添加,否则形成链表。
*/
public class HashSetTest1 {
public static void main(String[] args) {
HashSet<Person> hashSet = new HashSet<>();
Person person1 = new Person("刻晴",18);
Person person2 = new Person("七七",14);
Person person3 = new Person("琴",23);
hashSet.add(person1);
hashSet.add(person2);
hashSet.add(person3);
hashSet.add(person1);//重复的添加不进去
hashSet.add(new Person("七七",14));//能加进去了,因为这个认为是新对象,仅仅是名字和年龄相同。
// 重写equals方法和hashCode之后就添加不进去了
System.out.println("HashSet集合大小为: "+hashSet.size());
System.out.println("HashSet集合内容为: "+hashSet.toString());
//2.删除
hashSet.remove(person3);
System.out.println("HashSet集合大小为: "+hashSet.size());
System.out.println("HashSet集合内容为: "+hashSet.toString());
//3.遍历
//增强for,迭代器
for (Person p : hashSet) {
System.out.println(p.toString());
}
System.out.println("=============迭代器===============");
Iterator<Person> iterator = hashSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println(hashSet.contains(new Person("刻晴",18)));
System.out.println(hashSet.isEmpty());
}
}
TreeSet:
-
基于排列顺序实现元素不重复。
-
实现了SortedSet接口,对集合元素自动排序。
-
元素对象的类型必须实现Comparable接口,指定排序规则。
-
通过CompareTo方法确定是否为重复元素。
/**
* 使用TreeSet保存数据
* 存储结构:红黑树
* 元素必须实现comparable接口,compareTo()返回值是0表示认为是相同元素
*/
public class TreeSetTest {
public static void main(String[] args) {
TreeSet<Person> people = new TreeSet<>();
Person person1 = new Person("liming", 20);
Person person2 = new Person("meimei", 18);
Person person3 = new Person("acer", 14);
Person person4 = new Person("acer", 16);
people.add(person1);
people.add(person2);
people.add(person3);
people.add(person4);
System.out.println("treeSet集合大小: "+people.size());
System.out.println("treeSet内容为: "+people.toString());//java.lang.ClassCastException,
// 不重写compareTo方法就会报错
}
}
/**
* TreeSet的使用
* Comparator:实现定制比较(比较器)
* Comparable:可比较的
*/
public class ComparatorTest {
public static void main(String[] args) {
TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>() {
@Override
//创建集合,并制定比较规则
public int compare(Person o1, Person o2) {
int n1 = o1.getAge()-o2.getAge();
int n2 = o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
Person person1 = new Person("liming", 20);
Person person2 = new Person("meimei", 18);
Person person3 = new Person("acer", 14);
Person person4 = new Person("acer", 16);
persons.add(person1);
persons.add(person2);
persons.add(person3);
persons.add(person4);
System.out.println(persons.toString());
}
}
Map体系结构
-
Map接口的特点:
-
用于存储任意键值对(Key-Value)。
-
键:无序、无下标、不允许重复(唯一)。
-
值:无序、无下标、允许重复。
-
Map父接口
特点:存储一堆数据(key-value),无序、无下标,键不可重复,值可以重复。
方法:
-
v put(K key,v value)//将对象存入到集合中,关联键值。key重复则覆盖原值。
-
0bject get(Object key)//根据键获取对应的值。
-
Set<K>//返回所有key。
-
Collection<V> values()//返回包含所有值的Collection集合。
-
Set<Map.Entry<K,V>>//键值匹配的Set集合。
/**
* Map接口的使用
* 特点:(1)存储键值对(2)键不能重复值可以重复(3)无序
*/
public class MapTest {
public static void main(String[] args) {
//创建Map集合
Map<String, String> map = new HashMap<>();
//1.添加元素
map.put("521","我爱你");
map.put("1314","一生一世");
map.put("404","网页连接失败");
map.put("404","woc");//会覆盖
System.out.println("Map集合大小:"+map.size());
System.out.println("Map集合内容:"+map.toString());
//2.删除
map.remove("404");
System.out.println("删除后Map集合大小:"+map.size());
//3.遍历
//使用keySet()
System.out.println("============使用KeySet()================");
//Set<String> ks = map.keySet();
for (String s : map.keySet()) {
System.out.println(s+"-------"+map.get(s));
}
//使用entrySet()
System.out.println("============使用entrySet()================");
//Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+"-----------"+entry.getValue());
}
}
}
HashMap(重点)
JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value。.
/**
* hashMap的使用
* 存储结构:哈希表:(数组+红黑树+链表)
* 使用key和hashCode和equals作为判断重复的依据
*/
public class HashMapTest {
public static void main(String[] args) {
HashMap<Student, String> stu = new HashMap<>();
Student student1 = new Student("孙悟空", 89000);
Student student2 = new Student("猪八戒", 49000);
Student student3 = new Student("沙和尚", 19000);
Student student4 = new Student("唐僧", 30);
stu.put(student1,"战力第一");
stu.put(student2,"饭量第一");
stu.put(student3,"耐力第一");
stu.put(student4,"态度第一");
stu.put(student1,"运气第一");
System.out.println("元素个数:"+stu.size());
System.out.println("hashmap内容:"+stu.toString());
//遍历
//keySet()
System.out.println("=======keySet()=========");
for (Student s : stu.keySet()) {
System.out.println(s+"-------"+stu.get(s));
}
//使用entrySet()
System.out.println("============使用entrySet()================");
//Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<Student, String> entry : stu.entrySet()) {
System.out.println(entry.getKey()+"-----------"+entry.getValue());
}
//判断
System.out.println(stu.containsValue("运气第一"));
System.out.println(stu.isEmpty());
}
}
-
HashMap刚创建时, table是nu1l, 为了节省空间, 当添加第一 个元素时,table容量调整为16
-
当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数。
-
jdk1.8当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的提高执行效率
-
jdk1.8 当链表长度小于6时,调整成链表
-
jdk1.8以前,链表时头插入,jdk1. 8以后时是尾插入。
HashTabble(用的少)
-
JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。
Properties :(也少,后面流会学)
-
Hashtable的子类, 要求key和value都是String。 通常用于配置文件的读取。
TreeMap:
-
实现了SortedMap接口(是Map的子接口),可以对key自动排序。
/**
* TreeMap的使用
* 存储结构:红黑树
*/
public class TreeMapTest {
public static void main(String[] args) {
//新建集合
TreeMap<Student, String> treeMap = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n1 = o1.getAge() - o2.getAge();
int n2 = o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
//添加元素
Student student1 = new Student("孙悟空", 89000);
Student student2 = new Student("猪八戒", 49000);
Student student3 = new Student("沙和尚", 19000);
Student student4 = new Student("唐僧", 30);
treeMap.put(student1,"大地");
treeMap.put(student2,"高老庄");
treeMap.put(student3,"流沙河");
treeMap.put(student4,"东土大唐");
System.out.println("treemap集合大小:"+treeMap.size());
System.out.println("treemap内容:"+treeMap.toString());//java.lang.ClassCastException,
//要重写comparable接口
//遍历
//keySet()
System.out.println("=======keySet()=========");
for (Student s : treeMap.keySet()) {
System.out.println(s+"-------"+treeMap.get(s));
}
//使用entrySet()
System.out.println("============使用entrySet()================");
//Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<Student, String> entry : treeMap.entrySet()) {
System.out.println(entry.getKey()+"-----------"+entry.getValue());
}
}
}
Colletions工具类
-
概念:集合工具类,定义除了存取以外的集合常用方法。
-
方法:
-
public static void reverse(List<?> list) //反转集合中元素的顺序
-
public static void shuffle(List<?> list) //随机重置集合元素的顺序
-
public static void sort(List<T> list) //升序排序(元素类型必须实现Comparable接口)
/** * Collection工具类的使用 */ public class CollectionTest { public static void main(String[] args) { ArrayList<Integer> arrayList = new ArrayList<>(); arrayList.add(12); arrayList.add(443); arrayList.add(5345); arrayList.add(45); arrayList.add(1); arrayList.add(34); arrayList.add(543); //sort排序 System.out.println("排序前:"+arrayList.toString()); Collections.sort(arrayList); System.out.println("排序后:"+arrayList.toString()); //binarySearch二分查找 int a = Collections.binarySearch(arrayList,543); System.out.println(a); //copy复制 ArrayList<Integer> list = new ArrayList<>(); for (int i = 0; i < arrayList.size(); i++) { list.add(0); } Collections.copy(list,arrayList); System.out.println(list.toString()); //reverse反转 Collections.reverse(list); System.out.println("反转之后:"+list.toString()); //shuffle 打乱 Collections.shuffle(list); System.out.println("打乱之后:"+list.toString()); //集合转数组 System.out.println("======集合转数组=========="); Integer[] arr = list.toArray(new Integer[0]); System.out.println("数组"+ Arrays.toString(arr)); //数组转集合 System.out.println("=======数组转集合=========="); String[] names = {"张三","李四","王二麻子"}; List<String> list1 = Arrays.asList(names); list1.add("张飞");//UnsupportedOperationException //集合是一个受限集合不能添加和删除 System.out.println("集合"+list1.toString()); } }
-