一、集合
1.集合概念:
对象的容器,实现了对对象常用的操作,类似数组功能
2.集合和数组的区别
数组长度固定,集合长度不固定
数组可以存储基本类型和引用类型,集合只能引用类型
3.迭代器:专门用来遍历集合一种方式
hasNext();有下一个元素吗?有true,无false
next();获取下一个元素
remove();删除元素
4.List接口的特点:有序有下标,可重复
5.List常见的实现类
ArrayList
Vector
LinkedList
二、Collection接口
1.主要方法
collection.add()
collection.remove();
collection.isEmpty();
collection.clear();
collection.contains("镜");//判断是否包含该元素
2.重点
使用迭代器(迭代器专门用来遍历集合的一种方式)
Iterator it = collection.iterator();
while(it.hasNext()){
String s = (String)it.next();
System.out.println(s);
//不能使用collection删除方法
//collection.remove(s);
//it.remove();
}
System.out.println("元素个数:"+collection.size());
案例1
public class Demo01 {
public static void main(String[] args) {
//创建集合
Collection collection = new ArrayList();
// 添加元素
collection.add("颜奈斯");
collection.add("lisa");
collection.add("镜");
System.out.println("元素个数:"+collection.size());
System.out.println(collection);
// 删除元素
// collection.remove("镜");
// System.out.println("删除之后:"+collection.size());
// 遍历元素【重点】
//1.使用增强for
System.out.println("使用增强for");
for (Object object: collection) {
System.out.println(object);
}
//2.使用迭代器(迭代器专门用来遍历集合的一种方式)
//hasNext();有没有下一个元素
//next();读取下一个元素
//remove();删除当前元素
Iterator it = collection.iterator();
while(it.hasNext()){
String s = (String)it.next();
System.out.println(s);
//不能使用collection删除方法
//collection.remove(s);
//it.remove();
}
System.out.println("元素个数:"+collection.size());
// 判断
System.out.println(collection.contains("镜"));
System.out.println(collection.isEmpty());
}
}
案例2 保存学生信息
写一个Student实体类
public class Demo02 {
public static void main(String[] args) {
//新建Collection对象
Collection collection = new ArrayList();
Student s1 = new Student("颜奈斯",19);
Student s2 = new Student("lisa",20);
Student s3 = new Student("镜",18);
//1.添加数据
collection.add(s1);
collection.add(s2);
collection.add(s3);
System.out.println("元素个数:" +collection.size());
System.out.println(collection.toString());
//2.删除
//collection.remove(s1);
//collection.clear();
System.out.println("删除之后:"+ collection.size());
//3.遍历
for (Object object: collection ) {
Student s =(Student)object;
System.out.println(s);
}
//迭代器:hasNext(); next(); remove();
Iterator it = collection.iterator();
while(it.hasNext()){
Student s = (Student) it.next();
System.out.println(s.toString());
}
//判断
System.out.println(collection.contains(s1));
System.out.println(collection.isEmpty());
}
}
三、List接口
特点:有序,有下标,可以重复
主要方法
list.add("颜奈斯");
list.remove(0);//
list.get(i);//根据下标获取元素
list.indexOf("lisa");//获取位置
重点一
四种遍历集合方式
- for遍历
- foreach遍历
- 迭代器遍历
- 列表迭代器遍历
和Iterator的区别:
listIterator可以向前或向后遍历,添加,删除,修改元素
ListIterator lit = list.listIterator();
System.out.println("------------使用列表迭代器从前往后----------");
while (lit.hasNext()){
System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("------------使用列表迭代器从后往前----------");
while (lit.hasPrevious()){
System.out.println(lit.previousIndex()+":"+lit.previous());
}
public class Demo03 {
public static void main(String[] args) {
//先创建集合对象
List list = new ArrayList<>();
//1.添加元素
list.add("颜奈斯");
list.add("lisa");
list.add(0,"镜");
System.out.println("元素个数"+list.size());
System.out.println(list.toString());
//2.删除元素
//list.remove("lisa");
// list.remove(0);
// System.out.println("删除之后:"+ list.size());
// System.out.println(list.toString());
//for遍历
for (int i = 0; i<list.size();i++){
System.out.println(list.get(i));
}
//foreach遍历
for (Object object: list) {
System.out.println(object);
}
//迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//列表迭代器遍历
//和Iterator的区别,listIterator可以向前或向后遍历,添加,删除,修改元素
ListIterator lit = list.listIterator();
System.out.println("------------使用列表迭代器从前往后----------");
while (lit.hasNext()){
System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("------------使用列表迭代器从后往前----------");
while (lit.hasPrevious()){
System.out.println(lit.previousIndex()+":"+lit.previous());
}
//判断
System.out.println(list.contains("lisa"));
System.out.println(list.isEmpty());
//获取位置
System.out.println(list.indexOf("lisa"));
}
}
重点二
添加数字数据(自动装箱)已经不是int,而是自动变成了Integer
list.add(10);
删除不能直接删除,要么强转成Object,要么强转成Integer
list.remove(new Integer(20));
方法subList,返回子集合,含头不含尾
(开始的下标(包含),结束的下标(不包含))
List sub = list.subList(1,3);
System.out.println(sub.toString());
public class Demo04 {
public static void main(String[] args) {
//创建集合
List list = new ArrayList<>();
//1.添加数字数据(自动装箱)已经不是int,而是自动变成了Integer
list.add(10);
list.add(20);
list.add(30);
list.add(40);
list.add(50);
list.add(60);
System.out.println("元素个数:"+ list.size());
System.out.println(list.toString());
//2.删除操作
//删除不能直接删除,要么强转成Object,要么强转成Integer
// list.remove(new Integer(20));
System.out.println("删除元素:"+list.toString());
//3.补充方法subList,返回子集合,含头不含尾
List sub = list.subList(1,3);//(开始的下标(包含),结束的下标(不包含))
System.out.println(sub.toString());
}
}
List实现类
一、ArrayList使用【重点】
存储结构:数组,查找遍历速度快,增删慢
public class Demo05 {
public static void main(String[] args) {
//创建集合
ArrayList arrayList = new ArrayList<>();
//1.添加元素
Student s1 = new Student("颜奈斯",20);
Student s2 = new Student("lisa",20);
Student s3 = new Student("崛",20);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
System.out.println("元素个数:"+ arrayList.size());
System.out.println(arrayList.toString());
//2.删除元素
// arrayList.remove(new Student("lisa",20));
// System.out.println("删除后:"+ arrayList.size());
//3.遍历元素
//3.1使用迭代器
Iterator it = arrayList.iterator();
while (it.hasNext()){
Student s = (Student) it.next();
System.out.println(s.toString());
}
//3.2列表迭代器
ListIterator lit = arrayList.listIterator();
while(lit.hasNext()){
Student s = (Student) lit.next();
System.out.println(s.toString());
}
while (lit.hasPrevious()){
Student s = (Student) lit.previous();
System.out.println(s.toString());
}
//4.判断
System.out.println(arrayList.contains(new Student("lisa",20)));
System.out.println(arrayList.isEmpty());
//5.查找
System.out.println(arrayList.indexOf(new Student("lisa",20)));
}
}
重写equals方法
@Override
public boolean equals(Object o) {
//1.判断是不是同一个对象
if (this == o) {
return true;
}
//2.判断是否为空
if (o == null) {
return false;
}
//判断是否是Student类型
if (o instanceof Student) {
Student s = (Student)o;
//4.比较属性
if (this.name.equals(s.getName()) && this.age == s.getAge()) {
return true;
}
}
//5.不满足条件 ,返回false
return false;
}
二、Vector
存储结构:数组
public class Demo01 {
public static void main(String[] args) {
//创建集合
Vector vector = new Vector<>();
//1。添加元素
vector.add("奈斯");
vector.add("lisa");
vector.add("jin");
System.out.println("元素个数:"+vector.size());
//2.遍历
//2.1使用枚举器
Enumeration en = vector.elements();
while (en.hasMoreElements()){
String o = (String) en.nextElement();
System.out.println(o);
}
//判断
System.out.println(vector.contains("lisa"));
System.out.println(vector.isEmpty());
//vector其他方法
System.out.println(vector.firstElement());
System.out.println(vector.lastElement());
System.out.println(vector.get(0));
}
}
三、LinkedList
存储结构:双向链表
public class Demo02 {
public static void main(String[] args) {
//创建集合
LinkedList linkedList = new LinkedList<>();
//1.添加元素
Student s1 = new Student("颜奈斯",20);
Student s2 = new Student("lisa",20);
Student s3 = new Student("崛",20);
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
System.out.println("元素个数:"+linkedList.size());
System.out.println(linkedList.toString());
//2.删除
// linkedList.remove(s1);
// System.out.println("删除之后:"+ linkedList.size());
//遍历
//for
for (int i =0;i<linkedList.size();i++){
System.out.println(linkedList.get(i));
}
//foreach
for (Object object:linkedList) {
Student s = (Student) object;
System.out.println(s.toString());
}
//迭代器遍历
Iterator it = linkedList.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//列表迭代器遍历
//和Iterator的区别,listIterator可以向前或向后遍历,添加,删除,修改元素
ListIterator lit = linkedList.listIterator();
System.out.println("------------使用列表迭代器从前往后----------");
while (lit.hasNext()){
System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("------------使用列表迭代器从后往前----------");
while (lit.hasPrevious()){
System.out.println(lit.previousIndex()+":"+lit.previous());
}
}
}
ArrayList和LinkedList区别
四、泛型
1.泛型类
语法:类名
T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
用处:
- 创建变量
- 作为方法参数
- 作为方法返回值
public class MyGeneric<T> {
//1.创建变量
T t;
//2.作为方法参数
public void show(T t){
System.out.println(t);
}
//3.作为方法返回值
public T getT(){
return t;
}
}
注意:
- 使用泛型类创建对象,不能再是T,,后面的String可写可不写
- 泛型只能是引用类型
- 不同泛型类型对象之间不能相互赋值
public class TestGeneric {
public static void main(String[] args) {
//使用泛型类创建对象,不能再是T,,后面的String可写可不写
//注意:1.泛型只能是引用类型
//2.不同泛型类型对象之间不能相互赋值
MyGeneric<String> myGeneric = new MyGeneric<String>();
myGeneric.t="颜奈斯!";
myGeneric.show("lisa");
myGeneric.getT();
MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
myGeneric2.t=520;
myGeneric2.show(520);
myGeneric2.getT();
}
}
2.泛型接口
语法:接口名
注意:不能泛型静态常量,因为不知道类型
public interface MyInterface<T> { String name = "颜奈斯"; T server(T t); }
两种方式接口实现类
第一种 类实现接口时给了引用类型
public class MyInterfaceImpl implements MyInterface<String>{
@Override
public String server(String s) {
System.out.println(s);
return s;
}
}
测试
MyInterfaceImpl impl = new MyInterfaceImpl(); impl.server("颜奈斯你好!");
第二种 实现类接口也是泛型
public class MyInterfaceImpl2<T> implements MyInterface<T>{
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
测试才给定引用类型
MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<Integer>(); impl2.server(5201314);
3.泛型方法
语法: 返回值类型
public class MyGenericMethod {
//泛型方法
public <T> T show(T t){
T t2;
System.out.println("泛型方法"+t);
return t;
}
}
测试
方法给的参数是什么类型,泛型就是什么类型
//泛型方法 MyGenericMethod method = new MyGenericMethod(); method.show("颜奈斯!"); method.show(200); method.show(3.14);
4.泛型好处
1.提高代码的重用性
2.防止类型转异常,提高代码安全性
5.泛型集合
概念:
参数化类型,类型安全的集合,强制集合元素的类型必须一致
public class Demo03 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("xxx");
arrayList.add("yyy");
// arrayList.add(13);
// arrayList.add(45);
for (String str: arrayList){
System.out.println(str);
}
ArrayList<Student> arrayList2 = new ArrayList<Student>();
Student s1 = new Student("颜奈斯",20);
Student s2 = new Student("lisa",20);
Student s3 = new Student("崛",20);
arrayList2.add(s1);
arrayList2.add(s2);
arrayList2.add(s3);
Iterator<Student> iterator = arrayList2.iterator();
while(iterator.hasNext()){
Student next = iterator.next();
System.out.println(next);
}
}
}
五、set接口
特点:无序,无下标,不可重复
public class Demo01 {
public static void main(String[] args) {
//创建集合
Set<String> set = new HashSet<String>();
//1.添加数据
set.add("橘子");
set.add("香蕉");
set.add("苹果");
System.out.println("元素个数:"+set.size());
System.out.println(set.toString());
//2.删除
// set.remove("苹果");
// System.out.println(set.toString());
//foreach遍历
for (String string:set ) {
System.out.println(string);
}
//迭代器
Iterator<String> it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//判断
System.out.println(set.contains("苹果"));
System.out.println(set.isEmpty());
}
}
1.HashSet集合的使用
存储结构:哈希表(数组+链表+红黑树)
比如:火车站买票,数组是售票窗口,链表是排队
存储过程
(1)根据hashcode计算保存位置,如果此位置为空,则直接保存,如果不为空执行第二步
(2)再执行equals方法,如果equals方法为true,则认为是重复,否则形成链表
public class Demo02 {
public static void main(String[] args) {
//新建集合
HashSet<String> hashSet = new HashSet<>();
//添加元素
hashSet.add("橘子");
hashSet.add("香蕉");
hashSet.add("苹果");
hashSet.add("牛奶");
System.out.println("元素个数:"+hashSet.size());
System.out.println(hashSet.toString());
//删除
hashSet.remove("牛奶");
//遍历
//foreach
for (String string: hashSet) {
System.out.println(string.toString());
}
//迭代器
Iterator<String> it = hashSet.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//判断
System.out.println(hashSet.contains("橘子"));
System.out.println(hashSet.isEmpty());
}
}
2.TreeSet
存储结构:红黑树
二叉树:
一个节点只有两个子节点,左边的节点要小于右边的节点
public class Demo04 {
public static void main(String[] args) {
//创建集合
TreeSet<String> treeSet = new TreeSet<>();
//添加
treeSet.add("xyz");
treeSet.add("abc");
treeSet.add("hello");
System.out.println("元素个数:"+treeSet.size());
System.out.println(treeSet.toString());
//删除
// treeSet.remove("xyz");
// System.out.println(treeSet.toString());
//foreach
for (String string:treeSet) {
System.out.println(string.toString());
}
//迭代器
Iterator<String> it = treeSet.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//判断
System.out.println(treeSet.contains("abc"));
System.out.println(treeSet.isEmpty());
}
}
六、Map接口
特点:存储键值,键不能重复,值可以重复,无序
主要方法:
map.put("cn","中国");
map.keySet();//获取key
map.entrySet();//获取key和value
map.containsKey("cn");//判断是否存在key
map.containsValue("中国")//判断是都存在value
两种遍历方式
1.使用KeySet(); 获取key
Set<String> keySet = map.keySet();
for (String key: keySet ) {
System.out.println(key+"------"+map.get(key));
}
2.使用entrySet(); 获取key和value
for (Map.Entry<String,String> entry : map.entrySet() ) {
System.out.println(entry.getKey()+"------"+entry.getValue());
}
public class Demo01 {
public static void main(String[] args) {
//创建Map集合
Map<String,String> map = new HashMap<>();
//1.添加
map.put("cn","中国");
map.put("uk","英国");
map.put("usa","美国");
System.out.println("元素个数:"+map.size());
System.out.println(map.toString());
//删除
// map.remove("cn");
// System.out.println(map.size());
//遍历
//1.使用KeySet();
Set<String> keySet = map.keySet();
for (String key: keySet ) {
System.out.println(key+"------"+map.get(key));
}
//2.使用entrySet();
for (Map.Entry<String,String> entry : map.entrySet() ) {
System.out.println(entry.getKey()+"------"+entry.getValue());
}
//判断
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("中国"));
}
}
1.HashMap【重点】
存储结构:哈希表(数组+链表+红黑树)
使用key的hashcode和equals作为重复依据
重点:
遍历的两种方法
- keySet();
- entrySet();
注意点:
如何不让这个属性一样的对象添加进来?
//添加
Student s1 = new Student("颜奈斯", 20);
students.put(s1,"奥迪");
students.put(new Student("颜奈斯",20),"奥迪");
解决办法:对象类里重写hashcode和equals方法即可
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public class Demo02 {
public static void main(String[] args) {
//创建集合
HashMap<Student,String> students = new HashMap<>();
//添加
Student s1 = new Student("颜奈斯", 20);
Student s2 = new Student("lisa", 18);
Student s3 = new Student("露娜", 20);
students.put(s1,"奥迪");
students.put(s2,"奔驰");
students.put(s3,"大众");
//如何不让这个属性一样的对象添加进来?
//解决办法:对象类里重写hashcode和equals方法即可
students.put(new Student("颜奈斯",20),"奥迪");
System.out.println("元素个数:"+ students.size());
System.out.println(students.toString());
//删除
// students.remove(s1);
// System.out.println("删除之后:"+students.size());
//遍历
//1.keySet();
for (Student key: students.keySet()) {
System.out.println(key.toString()+"======="+students.get(key));
}
//2.entrySet()
for (Map.Entry<Student,String> entry: students.entrySet()) {
System.out.println(entry.getKey()+"====" +entry.getValue());
}
//判断
System.out.println(students.containsKey(new Student("颜奈斯",20)));
System.out.println(students.containsValue("当时的"));
}
}
总结
2.Hashtable【不常用】
1.Properties类
3.TreeMap
存储结构:红黑树
注意:(自动排序)
不能直接put引用类型,因为红黑树(二叉树)需要比较大小,遵循左小右大,所以要先在引用类(Student)实现Comparable接口,再重写compareTo方法
@Override
public int compareTo(Student o) {
//比较的属性自定义
int n = this.age-o.getAge();
return n;
}
public class Demo03 {
public static void main(String[] args) {
//创建集合
TreeMap<Student,String> treeMap = new TreeMap<Student,String>();
//添加
Student s1 = new Student("颜奈斯", 20);
Student s2 = new Student("lisa", 18);
Student s3 = new Student("露娜", 21);
treeMap.put(s1,"奥迪");
treeMap.put(s2,"奔驰");
treeMap.put(s3,"大众");
System.out.println("元素个数:"+ treeMap.size());
System.out.println(treeMap.toString());
//删除
treeMap.remove(new Student("露娜", 21));
System.out.println("删除后:" +treeMap.size());
//keySet();
for (Student key:treeMap.keySet()) {
System.out.println(key.toString()+"====="+treeMap.get(key));
}
//entrySet();
for (Map.Entry<Student,String> entry:treeMap.entrySet()) {
System.out.println(entry.getKey()+"====="+entry.getValue());
}
//判断
System.out.println(treeMap.containsValue("asd"));
System.out.println(treeMap.containsKey( new Student("露娜", 21)));
}
}
定制比较
//创建集合(定制比较)
TreeMap<Student,String> treeMap = new TreeMap<Student,String>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return 0;
}
});
七、Collections工具类
1.sort 排序 默认升序
//sort排序 默认升序
System.out.println("排序前:"+list.toString());
Collections.sort(list);
System.out.println("排序后:"+list.toString());
2.binarySearch 二分查找
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。
但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列
int i = Collections.binarySearch(list, 50); System.out.println(i);
3.copy 复制
List<Integer> dest = new ArrayList<>();
//保证准备复制的集合大小和复制的集合大小一样
for(int k =0;k<list.size();k++){
dest.add(0);
}
Collections.copy(dest,list);
System.out.println("复制后的:"+dest.toString());
4.reverse 反转
Collections.reverse(list); System.out.println("反转之后:"+list);
5. shuffle 打乱
Collections.shuffle(list); System.out.println("打乱之后:"+list);
6. list 转成 数组
System.out.println("-------list转成数组--------"); Integer[] arr = list.toArray(new Integer[0]); System.out.println(arr.length); System.out.println(Arrays.toString(arr));
7. 数组 转成 集合
System.out.println("-------数组变集合--------"); String[] names = {"颜奈斯","lisa","镜"}; //集合是一个受限集合,不能添加和删除 List<String> list2 = Arrays.asList(names); System.out.println(list2.toString());
注意
尽量不要用int[]数组,用Integer,否则会报错
Integer[] nums = {100,200,300,400}; List<Integer> ints = Arrays.asList(nums);
public class Demo04 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(20);
list.add(5);
list.add(30);
list.add(10);
list.add(50);
//sort排序 默认升序
System.out.println("排序前:"+list.toString());
Collections.sort(list);
System.out.println("排序后:"+list.toString());
//binarySearch 二分查找
//二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
int i = Collections.binarySearch(list, 50);
System.out.println(i);
//copy复制
List<Integer> dest = new ArrayList<>();
//保证准备复制的集合大小和复制的集合大小一样
for(int k =0;k<list.size();k++){
dest.add(0);
}
Collections.copy(dest,list);
System.out.println("复制后的:"+dest.toString());
//reverse反转
Collections.reverse(list);
System.out.println("反转之后:"+list);
//shuffle 打乱
Collections.shuffle(list);
System.out.println("打乱之后:"+list);
//补充:list转成数组
System.out.println("-------list转成数组--------");
Integer[] arr = list.toArray(new Integer[0]);
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
//数组转成集合
System.out.println("-------数组变集合--------");
String[] names = {"颜奈斯","lisa","镜"};
//集合是一个受限集合,不能添加和删除
List<String> list2 = Arrays.asList(names);
System.out.println(list2.toString());
//注意:尽量不要用int[]数组,用Integer,否则会报错
Integer[] nums = {100,200,300,400};
List<Integer> ints = Arrays.asList(nums);
}
}
八、总结
集合概念:
对象的容器,和数组相似,定义对多个对象进行操作的常用方法
List集合:
- 有序,有下标,可重复
- ArratList、linkedList、Vector(不用)
Set集合:
- 无序,无下标,不可重复
- HashSet、TreeSet
Map集合:
- 存储一对数据,无序,无下标,键不可重复,值可重复
- HashMap、HashTable、TreeMap
Collections工具类:
- 集合工具类,定义了除存取以外集合常用的方法