一、集合的概念:
-
概念:对象的容器,定义了对多个对象进行操作的方法。可实现数组的功能。
-
和数组的区别
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型
-
位置: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(Object o) //在此集合中移除o对象
- int size() //返回此集合中的元素个数
- Object[] toArray() //将此集合转换成数组
代码实例
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
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.size());
// System.out.println(collection);
// collection.clear();
// System.out.println("删除之后元素个数:" + collection.size());
// System.out.println(collection);
//遍历元素
//1.使用增强for
System.out.println("使用增强for-----------------");
for(Object object : collection){
System.out.println(object);
}
//2.使用迭代器(迭代器专门用来遍历集合的一种方式)
//hasNext();有没有下一个元素
//next();获取下一个元素
//remove();删除当前元素
System.out.println("使用迭代器-------------------");
Iterator it = collection.iterator();
while(it.hasNext()) {
String s = (String)it.next();
System.out.println(s);
//迭代过程中不能使用Collection删除方法
//collection.remove();抛出异常
//可以使用迭代器的删除方法
// it.remove();
}
System.out.println("元素个数:" + collection.size());
//判断
System.out.println(collection.contains("西瓜"));
System.out.println(collection.isEmpty());
}
}
结果
三、List子接口
- 特点:有序、有下标、元素可以重复
- 方法
- void add(int index, Object o) //在index位置插入对象o
- boolean addAll(int index, Collection c) //将一个集合中的元素添加到此集合中的index位置
- Object get(int index) //返回集合中指定位置的元素
- List subList(int fromIndex, int toIndex) //返回fromIndex和toIndex之间的集合元素
代码实例
package collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListTest {
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList<>();
//添加元素
list.add("苹果");
list.add("小米");
list.add(0,"华为");
System.out.println("元素个数:" + list.size());
System.out.println(list.toString());
//删除
list.remove(0);
System.out.println("删除之后:" + list.size());
System.out.println(list.toString());
//遍历
//1.使用for遍历
System.out.println("使用for遍历----------------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//2.使用增强for遍历
System.out.println("使用增强for遍历-------------");
for(Object object : list){
System.out.println(object);
}
//3.使用迭代器遍历
System.out.println("使用迭代器遍历--------------");
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//4.使用列表迭代器,和Iterator的区别,可以向前或向后遍历,添加、删除、修改元素
ListIterator lit = list.listIterator();
System.out.println("使用列表迭代器遍历-----------");
System.out.println("使用列表迭代器向后迭代:");
while(lit.hasNext()){
System.out.println(lit.next());
}
System.out.println("使用列表迭代器向前迭代:");
while(lit.hasPrevious()){
System.out.println(lit.previous());
}
//获取
System.out.println(list.indexOf("苹果"));
}
}
四、List实现类
-
ArrayList
- 数组结构实现,查询快、增删慢
- JDK1.2版本,运行效率快、线程不安全
-
Vector
- 数组结构实现,查询快、增删慢
- JDK1.0版本,运行效率慢、线程安全
-
LinkedList
- 链表结构实现,增删快,查询慢
ArrayList方法使用和其他方法一样
重写equals方法实现用new对象删除数组元素
- remove()方法使用equals()方法比较对象的地址来进行删除操作
- 改写equals()方法,remove()方法也会随之改变
重写之后的Student类
package collection;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public void setAge(){
this.age = age;
}
@Override
public String toString() {
return "Student[name:" + name + "age:" + age + "]";
}
@Override
public boolean equals(Object obj) {
//判断是不是一个对象
if(this==obj){
return true;
}
//判断是否为空
if(obj==null){
return false;
}
//判断是否是Student类型
if(obj instanceof Student){
Student s = (Student)obj;
//比较属性
if(this.name.equals(s.getName())&&this.age==s.getAge()){
return true;
}
}
//不满足条件返回false
return false;
}
}
ArrayTest
package collection;
import java.util.ArrayList;
/**
* ArrayList的使用
* 存储结构:数组,查找遍历速度快,增删慢
*/
public class ArrayListTest {
public static void main(String[] args) {
//创建集合
ArrayList arrayList = new ArrayList();
Student s1 = new Student("张三",11);
Student s2 = new Student("李四", 13);
Student s3 = new Student("王二",14);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
arrayList.remove(new Student("张三",11));
System.out.println("删除之后元素个数:" + arrayList.size());
System.out.println(arrayList);
}
}
Vector的使用
package collection;
import java.util.Enumeration;
import java.util.Vector;
public class VectorTest {
public static void main(String[] args) {
//创建集合
Vector vector = new Vector();
//添加元素
vector.add("草莓");
vector.add("芒果");
vector.add("西瓜");
System.out.println("元素个数:" + vector.size());
//遍历:使用枚举器
Enumeration en = vector.elements();
while(en.hasMoreElements()){
String o = (String)en.nextElement();
System.out.println(o);
}
//其他方法
//firstElement\lastElement\elementAt()
}
}
五、泛型
-
Java泛型是JDK1.5中引进的一个新特性,其本质是参数化类型,把类型作为参数传递
-
常见的形式有:泛型类、泛型接口、泛型方法
-
语法:
*<T,…> T称为类型占位符,表示一种引用类型
-
好处
- 提高代码的重用性
- 防止类型转换异常,提高代码的安全性
泛型类
package myGeneric;
public class MyGeneric<T> {
//使用泛型T
//创建变量
T t;
//泛型作为方法的参数
public void show(T t){
System.out.println(t);
}
//泛型作为方法的返回值
public T getT(){
return t;
}
}
package myGeneric;
public class GenericTest {
public static void main(String[] args) {
//使用泛型创建对象
//不同泛型对象之间不能互相赋值
//泛型只能使用引用类型
MyGeneric<String> myGeneric = new MyGeneric<String>();
myGeneric.t = "hello";
myGeneric.show("hello, everyone");
String string = myGeneric.getT();
MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
myGeneric2.t = 100;
myGeneric2.show(200);
Integer integer = myGeneric2.getT();
}
}
泛型接口
package myGeneric;
public class MyInterfaceImp implements MyInterface<String> {
@Override
public String server(String s) {
System.out.println(s);
return s;
}
}
package myGeneric;
public class MyInterfaceImp2<T> implements MyInterface<T> {
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
MyInterfaceImp imp1 = new MyInterfaceImp();
imp1.server("xxxxx");
MyInterfaceImp2 imp2 = new MyInterfaceImp2();
imp2.server(1000);
泛型方法
package myGeneric;
/**
* 泛型方法
* 语法: <T> 返回值类型
*/
public class MyGenericMethod {
//泛型方法
public <T> void show(T t){
System.out.println("泛型方法:" + t);
}
public <T> T test(T t){
System.out.println("泛型方法");
return t;
}
}
MyGenericMethod myGenericMethod = new MyGenericMethod();
myGenericMethod.show("中国加油"); //根据传入的参数自动确定类型
泛型集合
- 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致
- 特点:
- 编译时即可检查,而非运行时抛出异常
- 访问时,不必类型转换
- 不同泛型之间引用不能相互赋值,泛型不存在多态
六、Set子接口
- 特点:无序、无下标、元素不可重复
- 方法:全部继承自Collection中的方法
HashSet集合
- 基于HashCode计算元素存放的位置
- 当存入的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入
package set;
import java.util.HashSet;
/**
* HashSet集合的使用
* 存储结构:哈希表(数组+链表+红黑树)
* 存储过程
* (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步
* (2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
*/
public class HashSetTest {
public static void main(String[] args) {
//新建一个集合
HashSet<Person> persons = new HashSet<Person>();
//添加元素
Person p1 = new Person("刘德华", 20);
Person p2 = new Person("林志玲", 22);
Person p3 = new Person("梁朝伟", 25);
persons.add(p1);
persons.add(p2);
persons.add(p3);
persons.add(new Person("梁朝伟",25));
System.out.println("元素个数:" + persons.size());
System.out.println(persons.toString());
}
}
package set;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public void setAge(){
this.age = age;
}
@Override
public int hashCode() {
int n1 = this.name.hashCode();
int n2 = this.age;
return n1 + n2;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj == null){
return false;
}
if(obj instanceof Person){
Person p = (Person)obj;
if (this.name.equals(p.getName()) && this.age == p.getAge()) {
return true;
}
}
return false;
}
@Override
public String toString() {
return "Person[name:" + name + ",age:" + age + "]";
}
}
TreeSet
- 基于排序算法实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序
- 元素对象的类型必须实现Comparable接口,指定排序规则
- 通过CompareTo方法确定是否为重复元素
package set;
import java.util.TreeSet;
/**
* 使用TreeSet存储数据
* 存储结构:红黑树
* 要求:元素必须实现Comparable接口,compareTo()方法返回值为0,认为是重复元素
*/
public class TreeSetTest {
public static void main(String[] args) {
TreeSet<Person> persons = new TreeSet<>();
Person p1 = new Person("xyz", 20);
Person p2 = new Person("hello", 22);
Person p3 = new Person("zhangsan", 25);
persons.add(p1);
persons.add(p2);
persons.add(p3);
System.out.println("元素个数:" + persons.size());
System.out.println(persons.toString());
}
}
package set;
import java.util.Objects;
public class Person implements Comparable<Person>{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public void setAge(){
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Person[name:" + name + ",age:" + age + "]";
}
@Override
public int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.age - o.getAge();
return n1==0?n2:n1;
}
}
Comparatord(比较器)
package set;
import java.util.Comparator;
import java.util.TreeSet;
/**
* 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 p1 = new Person("xyz", 20);
Person p2 = new Person("hello", 22);
Person p3 = new Person("zhangsan", 25);
persons.add(p1);
persons.add(p2);
persons.add(p3);
System.out.println(persons.toString());
}
}
七、Map集合
-
Map接口的特点:
- 用于存储任意键值对(Key-value)
- 键:无序、无下标、不允许重复
- 值:无序、有下标、允许重复
-
方法:
- V put(K key, V value) //将对象存入到集合中,关联键值。key重复则覆盖
- Object get(Object key) //根据键获取相应的值
- Set //返回所有的key
- Collection value() //返回包含所有值的Collection集合
- Set<Map.Entry<K,V>> //键值匹配的Set集合
package mapSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Map接口的使用
*/
public class MapSetTest {
public static void main(String[] args) {
//创建Map集合
Map<String, String> map = new HashMap<>();
//添加元素
map.put("cn", "中国");
map.put("uk", "英国");
map.put("usa", "美国");
map.put("cn", "zhongguo");//key相同,取代之前的值
System.out.println("元素个数:" + map.size());
System.out.println(map.toString());
//删除
map.remove("usa");
System.out.println("删除之后:" + map.size());
//遍历
//使用keySet方法
// Set<String> keyset = map.keySet();
System.out.println("使用keySet方法--------------");
for (String key : map.keySet()) {
System.out.println(key + "," + map.get(key));//输出键值和值
}
//使用entrySet方法
System.out.println("使用entrySet方法------------");
Set<Map.Entry<String,String>> entries = map.entrySet();
for(Map.Entry<String,String> entry : entries){
System.out.println(entry.getKey() + "," + entry.getValue());
}
}
}
HashMap(后续单独总结)
- JDK1.2版本,线程不安全,运行效率快;运行用null作为key或是value
Hashtable
- JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value
Properties
- Hashtable的子类,要求key和value都是String。通常用于配置文件的读取
TreeMap
- 实现了SortedMap接口(是Map的子接口),可以对key自动排序
太懒了,后面有时间再完善