java常用集合框架
程序员文章站
2024-03-15 09:47:29
...
集合框架
集合
- 集合是java提供的一种容器,用来储存多个数据
- 集合与数组的区别
- 数组的长度是固定的,集合的长度是可变的
- 数组中存储的是同一类型的元素,可以存储基本数据类型
- 集合中存储的都是对象,而且对象的类型可以不一致
- 在开发中对象多的时候一般使用结合
集合框架
ArrayList集合
对象数组
package arraylist01;
/*
题目
生成3个person类数组
缺点
数组建立好之后,在程序运行中长度不会改变
*/
public class Demo01 {
public static void main(String[] args) {
//首先创建一个长度为3的数组,里面用来存放Person对象
Person[] p=new Person[3];
Person one = new Person("迪丽热巴", 18);
Person two = new Person("古力娜扎", 19);
Person three = new Person("007", 20);
p[0]=one;
p[1]=two;
p[2]=three;
System.out.println(one);//aaa@qq.com 地址值
System.out.println(p[0].getName()+" "+p[0].getAge());
}
}
ArrayList集合概述与基本使用
package arraylist01;
import java.util.ArrayList;
/*
java.util.ArrayList
数组的长度不可以发生改变,但是ArrayList的长度是可以改变的
对于ArrayList来说有一个尖括号<E>代表泛型
泛型,也就是装在集合当中的元素,全都是统一的类型
注意
泛型只能是引用类型,不能是基本类型
对于ArrayList集合来说直接打印,显示的不是地址值,而是集合中的内容
如果集合为空,则打印一个空的中括号[]
*/
public class Demo02 {
public static void main(String[] args) {
//创建了一个集合list,存储的数据类型为String类型
//从JDK1.7之后,右边的括号里可以不写类型,但是尖括号不能少
ArrayList<String> list = new ArrayList<>();
System.out.println(list);//[]
//向集合中添加事物,用add方法
list.add("孙悟空");
System.out.println(list);//[孙悟空]
list.add("猪八戒");
list.add("沙悟净");
list.add("白龙马");
System.out.println(list);//[孙悟空, 猪八戒, 沙悟净, 白龙马]
}
}
ArrayList集合常用方法
package arraylist01;
import java.util.ArrayList;
/*
ArrayList集合常用的方法
public Boolean add(E e); 向集合中添加元素,E与泛型对应,返回值代表是否添加成功
对于ArrayList集合添加一定成功,但是对于其他集合就不一定
public E get(int index ); 从集合中取出元素,参数为索引编号,从0开始,返回值就是对应位置的元素
public E remove(int index ); 从集合中删除元素,参数为索引编号,返回值就是删除的的元素
public int size(); 获取集合的长度,返回值是集合中包含元素的个数
*/
public class Demo03 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
boolean b1 = list.add("美食家老八");
System.out.println(list);//[美食家老八]
System.out.println(b1);;//true
list.add("冬泳怪鸽");
list.add("乔碧萝");
list.add("李小璐");
list.add("徐大SAO");
System.out.println(list);//[美食家老八, 冬泳怪鸽, 乔碧萝, 李小璐, 徐大SAO]
System.out.println(list.get(4));//获取索引值为3的元素,并打印
System.out.println(list.remove(3));//删除集合中3号索引的元素,返回值为删除元素
System.out.println(list);//重新打印集合元素
//获取集合的长度尺寸,也就是集合中的元素的个数
int size=list.size();
System.out.println(size);
//遍历集合
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
ArrayList集合存储基本类型
package arraylist01;
import java.util.ArrayList;
/*
如果想要往集合里放基本类型,就是用基本集合的包装类
基本类型不能放在集合的原因是,基本类型没有地址值,集合保存的是地址值
*/
public class Demo04 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(100);
list.add(200);
list.add(300);
int num=list.get(0);
System.out.println("第一个元素是"+num);
}
}
练习
随机添加6个1-33的数字,添加到集合,并且遍历
package arraylist01;
import java.util.ArrayList;
import java.util.Random;
/*
随机添加6个1-33的数字,添加到集合,并且遍历
*/
public class Demo05Text {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 6; i++) {
list.add(random.nextInt(33)+1);
}
for (Integer integer : list) {
System.out.println(integer);
}
}
}
自定义四个学生对象,添加到集合并且遍历
package arraylist01;
import java.util.ArrayList;
/*
题目
自定义四个学生对象,添加到集合并且遍历
*/
public class Demo06Text {
public static void main(String[] args) {
ArrayList<Person> p = new ArrayList<>();
Person p1 = new Person("美食家老八",18);
Person p2 = new Person("奥利给",19);
Person p3 = new Person("干了",20);
Person p4 = new Person("兄弟们",21);
p.add(p1);
p.add(p2);
p.add(p3);
p.add(p4);
for (int i = 0; i < p.size(); i++) {
System.out.println(p.get(i).getName()+"\t\t\t"+p.get(i).getAge());
}
}
}
package arraylist01;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
定义指定格式的打印集合方法(ArrayList为参数格式)
package arraylist01;
import java.util.ArrayList;
/*
定义指定格式的打印集合方法(ArrayList为参数格式),使用括号{}括起来,用@分割
格式 {元素@元素@元素}
*/
public class Demo07Text {
public static void main(String[] args) {
ArrayList<Integer> i1 = new ArrayList<>();
for (Integer i = 0; i < 10; i++) {
i1.add(i);
}
printf(i1);
}
private static void printf(ArrayList<Integer> a) {
System.out.print("{"+a.get(0));
for (int i = 1; i < a.size(); i++) {
System.out.print("@"+a.get(i));
}
System.out.print("}");
}
}
用一个大集合,存入20个随机数字,然后筛选里面的偶数,放到小集合中。使用自定义方法来筛选
package arraylist01;
import java.util.ArrayList;
import java.util.Random;
/*
题目
用一个大集合,存入20个随机数字,然后筛选里面的偶数,放到小集合中。
使用自定义方法来筛选
*/
public class Demo08Text {
public static void main(String[] args) {
Random random = new Random();
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<Integer> list3 = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list1.add(random.nextInt(101));
}
for (int i = 0; i < 20; i++) {
System.out.print(list1.get(i)+" ");
}
System.out.println();
list3=shu(list1);
list3=shu(list1);
for (int i = 0; i < list3.size(); i++) {
System.out.print(list3.get(i)+" ");
}
}
//接受大集合数据,返回小集合
private static ArrayList<Integer> shu(ArrayList<Integer> a) {
ArrayList<Integer> list2 = new ArrayList<>();
for (int i = 0; i < a.size(); i++) {
//int num=a.get(i);
if(a.get(i)%2==0){
list2.add(a.get(i));
}
}
return list2;
}
}
Collection集合
package collection01;
import java.util.ArrayList;
import java.util.Collection;
/*
java.util.Collection
所有单列集合最顶层的接口,里面定义了所有单列集合的共性方法
任意单列集合都可以使用Collection中的方法
共性的方法
public boolean add(E e) 把给定对象添加到当前集合
public void clear() 从此集合中删除所有元素(可选操作)。
public boolean remove(E e) 从该集合中删除指定元素的单个实例(如果存在)(可选操作)。
public boolean contains(E e) 如果此集合包含指定的元素,则返回 true 。
public boolean isEmpty() 判断集合为空,则返回 true 。
public int size() 返回此集合中的元素数。
public Object[] toArray() 把集合中的元素存储到数组中
*/
public class Demo01 {
public static void main(String[] args) {
//创建集合对象可以使用多态,接口指向实现类
Collection<String> coll = new ArrayList<>();
System.out.println(coll); //重写了toString方法 []
/*
public boolean add(E e) 把给定对象添加到当前集合
返回值为布尔值,一般都返回true,因此一般不接受
*/
boolean b1=coll.add("李四");
System.out.println("b1="+b1); //b1=true
System.out.println(coll); //[李四]
coll.add("wkjhjkhk");
coll.add("wkjhkhk");
coll.add("wkjhfgjkhk");
coll.add("wkjkhk");
System.out.println(coll);//[李四, wkjhjkhk, wkjhkhk, wkjhfgjkhk, wkjkhk]
/*
public boolean remove(E e) 从该集合中删除指定元素的单个实例
如果删除成功就返回true
如果删除对象不存在,就返回false
*/
boolean b2 = coll.remove("wkjhfgjkhk");
System.out.println("b2="+b2);
System.out.println(coll);
/*
public boolean contains(E e) 如果此集合包含指定的元素,则返回 true 。
*/
boolean b3 = coll.contains("张三");
System.out.println("b3="+b3);
//判断集合是否为空, public boolean isEmpty() 是空返回true
boolean b4 = coll.isEmpty();
System.out.println("b4="+b4);
//public int size() 返回此集合中的元素数。
int s1 = coll.size();
System.out.println("s1="+s1);
//public Object[] toArray() 把集合中的元素存储到数组中
Object[] objects = coll.toArray();
for (int i = 0; i < objects.length; i++) {
System.out.print(objects[i]+" ");
}
// public void clear() 从此集合中删除所有元素,集合还存在
coll.clear();
System.out.println(coll);
}
}
Iterator迭代器
-
迭代,即Collection集合元素通用的获取方式。在取元素之前先判断集合中有没有元素,如果有就把这个元素取出来,继续判断,如果还有就继续取出来,,一直把集合中所有元素都取出来。这个过程就叫迭代。
-
迭代器概述
package collection01;
/*
java.util.Iterator,迭代器,用于遍历集合
有两个常用方法
boolean hasNext() 如果还有更多的元素迭代,则返回true 。
判断集合中还有没有下一个元素,有就返回true
E next() 返回迭代中的下一个元素。
取出集合中的下的一个
Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊
Collection接口中有一个方法叫iterator(),这个方法就是
迭代器的使用步骤
1.使用集合中的方法iterator(),获取迭代器实现类对象,使用Iterator接口来接收它()
2.使用Iterator接口中的方法,hasNext判断还有没有下一个元素
3.使用Iterator接口中的方法,naxt方法取出下一个元素
*/
public class Demo02 {
public static void main(String[] args) {
}
}
- 迭代器代码实现
package collection01;
import java.util.ArrayList;
import java.util.Iterator;
/*
java.util.Iterator,迭代器,用于遍历集合
有两个常用方法
boolean hasNext() 如果还有更多的元素迭代,则返回true 。
判断集合中还有没有下一个元素,有就返回true
E next() 返回迭代中的下一个元素。
取出集合中的下的一个
Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊
Collection接口中有一个方法叫iterator(),这个方法就是
迭代器的使用步骤
1.使用集合中的方法iterator(),获取迭代器实现类对象,使用Iterator接口来接收它()
2.使用Iterator接口中的方法,hasNext判断还有没有下一个元素
3.使用Iterator接口中的方法,naxt方法取出下一个元素
*/
public class Demo02 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
list.add("田七");
/*
1.使用集合中的方法iterator(),获取迭代器实现类对象,使用Iterator接口来接收它(多态)
注意
Iterator迭代器也是有泛型的,迭代器的泛型跟着集合走,集合是什么,迭代器就是什么
*/
/* //多态 接口 实现类
Iterator<String> it = list.iterator();
// 2.使用Iterator接口中的方法,hasNext判断还有没有下一个元素
boolean b = it.hasNext();
System.out.println(b);
// 3.使用Iterator接口中的方法,naxt方法取出下一个元素
String s = it.next();
System.out.println(s);*/
Iterator<String> it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("================================================");
for (Iterator<String> it1 = list.iterator();it1.hasNext(); ) {
System.out.println(it1.next());
}
}
}
- 迭代器实现原理
增强For循环
- 也称为for each循环,是Jdk1.5后出来的新特性,专门用来遍历数组和集合。它的内部原理是Iterator迭代器,所以在遍历操作中不能有增删操作。使用for循环的外壳,简化了迭代器的书写
- public interface Collection extends Iterable
- 必须要有遍历的目标,目标只能是Collection或数组,仅仅作为遍历对象出现
泛型
概述
- 在前面学习集合时,我们知道集合可以存放任意对象的,只要把对象存储在集合中,那么这时他们都会被提升为Object类型,当我们取出相应的对象,并进行相应的操作,必须进行相应的类型转换。
- 泛型是一种未知的数据类型,当我们不知道是用什么数据类型时,使用泛型
- 泛型也可以看成一个变量,来接收数据类型
使用泛型的好处
package fanxing;
import java.util.ArrayList;
import java.util.Iterator;
public class Demo01 {
public static void main(String[] args) {
shoe01();
show02();
}
/*
创建一个集合对象,使用泛型
好处
1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
2.把运行期异常,提前到来编译期
弊端
泛型是什么类型就只能用什么类型
*/
private static void show02() {
ArrayList<String> list = new ArrayList<>();
list.add("hsuhjiujhi");
list.add("hduihiuowhjui");
//list.add(122); //(java.lang.String) in ArrayList cannot be applied to (int)
Iterator<String> it = list.iterator();
while (it.hasNext()){
String next = it.next();
System.out.println(next+" "+next.length());
}
}
/*
创建一个集合对象,不使用泛型
好处
1.集合不使用泛型,默认类型就是Object类型,可以存储任意类型的数据
弊端
不安全,会引发异常
*/
private static void shoe01() {
ArrayList a1 = new ArrayList<>();
a1.add("jdicjij");
a1.add(123);
//使用迭代器,来遍历数据
Iterator it = a1.iterator();
while(it.hasNext()){
Object obj=it.next();
System.out.println(obj);
//想要使用String类型的llength方法,不能用,Object obj=it.next();多态不能使用自雷特有的方法
//需要向下转型
//会抛出类型转异常,不能把Integer转换为String
//String s=(String)obj;
//System.out.println(s.length());//ClassCastException
}
}
}
泛型的定义与使用
package fanxing;
public class Demo02text {
public static void main(String[] args) {
//不写泛型默认为Object类型
Demo02 demo02 = new Demo02();
demo02.setName("djhdqhdiuqio");
System.out.println(demo02.getName());
Demo02<Object> objectDemo02 = new Demo02<>();
objectDemo02.setName(1233);
System.out.println(objectDemo02.getName());
}
}
2
package fanxing;
/*
定义一个含有泛型的类,模拟ArraysList集合
泛型是一个未知的数据类型,当我们不确定使用什么数据类型时,可以使用泛型
泛型可以是接收任意的数据类型,可以是Integer,String,等
创建对象时,可以确定泛型的数据类型
*/
public class Demo02<E> {
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
含有泛型的方法
-
定义含有泛型的方法,泛型定义在方法的修饰符和返回值之间
-
格式
修饰符 <泛型> 返回值类型 方法名(参数列表(泛型类型)){
方法体
}
-
含有泛型的方法,在调用方法的时候确定泛型的数据类型
-
传递什么类型的参数,泛型就是什么类型
泛型的通配符
- 不知道使用什么来接受的时候,此时可以使用“?”,表示未知通配符
- 此时只能接受数据,不能往集合里存储数据
List集合
- 有序的集合,存储和取出元素是一致的
- 有索引
- 与set不同,List允许存储重复的元素
package listtext;
/*
java.util.List接口,extends Collections接口
List集合的三大特点
1.有序,存储元素和取出元素的顺序是一致的
2.有索引,包含了一些使用索引的方法
3.允许存储重复元素
List接口中带索引的方法(特有)
1.add(int index, E element) 将指定的元素插入此列表中的指定位置
2.get(int index) 返回此列表中指定位置的元素。
3.set(int index, E element) 用指定的元素(可选操作)替换此列表中指定位置的元素。
4.remove(int index) 删除该列表中指定位置的元素
注意
操作索引时,一定要防止索引越界异常
*/
public class listtext {
}
ArrayList集合
- 增删慢,查找快(类似于数组)
LikedList集合
- 增删快,查找慢(类似于链表)
package listtext;
/*
java.util.LinkedList集合,implement List接口
LinkedList集合的特点
1.底层是一个链表结构
2.里面包含了大量操作首位元素的方法
注意
使用LinkedList的特有用方法时,不能使用多态
addFirst(E e) 在该列表开头插入指定的元素。
addLast(E e) 将指定的元素追加到此列表的末尾。
getFirst() 返回此列表中的第一个元素。
getLast() 返回此列表中的最后一个元素。
removeFirst() 从此列表中删除并返回第一个元素。
removeLast() 从此列表中删除并返回最后一个元素。
pop() 从此列表表示的堆栈中弹出一个元素。
push(E e) 将元素推送到由此列表表示的堆栈上。
isEmpty() 如果列表不包含元素,返回1true
*/
public class LinkedList {
}
Vector集合
- 可以实现可增长的对象数组
- 单线程
Set接口
-
set继承了Collection接口
-
set不包含重复的元素
-
无索引,因此他没有带索引的方法
package settext;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*
java.util.Set接口,extends collection接口
Set接口的特点
1.不允许储存重复元素
2.没有索引,也不能使用带索引的方法,不能使用普通for循环1遍历
java.util.HashSet集合,implement Set接口
HashSet接口的特点
1.不允许储存重复元素
2.没有索引,也不能使用带索引的方法,不能使用普通for循环1遍历
3.是一个无序的1集合,存储元素与取出元素的顺序可能不一致
4.底层是一个哈希表结构(查询速度快)
*/
public class Demo01set {
public static void main(String[] args) {
Set<Integer> integers = new HashSet<>();
//使用add方法往集合中添加元素
integers.add(5);
integers.add(4);
integers.add(3);
integers.add(5);
//使用迭代器,遍历
Iterator<Integer> it = integers.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//使用增强for
System.out.println("==========================");
for (Integer integer : integers) {
System.out.println(integer);
}
}
}
hashCode方法
package settext;
/*
哈希值,他是一个十进制的整数,有系统随机给出(实际就是对象存储的逻辑地址,是模拟出来的地址,不是真实的物理地址)
在object类中有一个1方法来获取,对象的哈希值
HashCode方法源代码
public native int hashCode();
native,代表方法调用的是本地操作系统的方法
*/
public class Demo02HashCode {
public static void main(String[] args) {
//Person类继承了Object类,因此可以使用Object类中的方法,HashCode
Person p1 = new Person();
int h1 = p1.hashCode();
System.out.println(h1);
//toString源码
// return getClass().getName() + "@" + Integer.toHexString(hashCode());
//就是把10进制哈希值,变为16进制哈希值
System.out.println(p1);
/*
String类重写了hashCode方法
*/
String a1 = new String("nb");
String a2 = new String("nb");
System.out.println(a1.hashCode());
System.out.println(a2.hashCode());
//巧合,字符串不一样,哈希值相同
System.out.println("重地".hashCode());//1179395
System.out.println("通话".hashCode());//1179395
}
}
哈希表
HashSet存储不重复的原理
package settext;
import java.util.HashSet;
/*
Set集合不能存储重复数据的原理
*/
public class Demo03HashSet {
public static void main(String[] args) {
HashSet<String> h1 = new HashSet<>();
String s1 = new String("abc");
String s2 = new String("abc");
h1.add(s1);
h1.add(s2);
h1.add("重地");
h1.add("通话");
h1.add("abc");
System.out.println(h1);//[重地, 通话, abc]
}
}
HashSet存储自定义类型元素
package settext;
import java.util.HashSet;
/*
HashSet存储自定义类型元素
set集合存储元素唯一
存储元素必须重写hashCode和equals方法
以保证同名,同龄人看做同一个人
*/
public class Demo04HashSet {
public static void main(String[] args) {
HashSet<Person> h1 = new HashSet<>();
Person p1 = new Person("张三",18);
Person p2 = new Person("张三",18);
Person p3 = new Person("张三",19);
h1.add(p1);
h1.add(p2);
h1.add(p3);
System.out.println(h1);
}
}
/*
package settext;
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
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);
}
}
*/
LinkedHashSet集合
package settext;
import java.util.HashSet;
import java.util.LinkedHashSet;
/*
java.util.LinkedHashSet集合 extends HashSet集合
LinkedHashSet集合的特点
底层是一个哈希表,数组+链表、红黑树+链表(多了一条链表,用来记录存储的顺序,保证元素有序)
*/
public class Demo05HashSet {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("abc");
set.add("abc");
set.add("qqq");
set.add("qqw");
set.add("ggg");
System.out.println(set);//无序,不允许重复
LinkedHashSet<String> set1 = new LinkedHashSet<>();
set.add("abc");
set.add("abc");
set.add("qqq");
set.add("qqw");
set.add("ggg");
System.out.println(set);//有序,不允许重复
}
}
可变参数
package settext;
/*
可变参数,JDK1.5之后的出现的新特性
使用前提
当方法的参数列表,数据类型已确定,但参数个数不确定,就可以使用可变参数
使用格式,定义方法时,使用
修饰符 返回值类型 方法名(数据类型···变量名){}
可变参数的原理
可变参数的底层就是一个数组,根据传递参数个数的不同,会创建不同长度的数组,来存储这些参数
传递参数的个数可以是0个(不传递参数),1,2,3····多个
注意事项
一个方法传递的参数,只能有一个可变参数
如果方法的参数有有多个,可变参数必须写在末尾
*/
public class Demo06Var {
public static void main(String[] args) {
int a=add(1,2,3,4,5,6,7,8,9);
System.out.println(a);
}
//计算多个int的和
//已知数据类型,但是参数的个数未知
public static int add(int...arr){
//System.out.println(arr);
int a=0;
for (int i = 0; i <arr.length ; i++) {
a=a+arr[i];
}
return a;
}
}
Collections集合工具类
package collectionstext;
import java.util.ArrayList;
import java.util.Collections;
/*
java.util.Collections ,用来对集合进行操作
public static <T> boolean addAll(Collection<? super T> c, T... elements) 将所有指定的元素添加到指定的集合。
public static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表。
static <T> void sort(List<T> list) 根据其元素的natural ordering对指定的列表进行排序。 升序排序
注意
sort(List<T> list)使用前提
被排序的集合里储存的元素,必须实现Comperable,重写接口中的方法comperTo定义排序的规则
自己(this)-参数 升序
反之 降序
*/
public class Demo01 {
public static void main(String[] args) {
ArrayList<String> a1 = new ArrayList<>();
a1.add("a");
a1.add("b");
a1.add("c");
a1.add("d");
a1.add("e");
System.out.println(a1);//[a, b, c, d, e]
ArrayList<String> a2 = new ArrayList<>();
Collections.addAll(a2,"a","b","c","d","e");
System.out.println(a2);//[a, b, c, d, e]
Collections.shuffle(a2);
System.out.println(a2);//[e, c, b, a, d]
Collections.sort(a2);
System.out.println(a2);//[a, b, c, d, e]
ArrayList<Integer> i1 = new ArrayList<>();
Collections.addAll(i1,1,45,78,265,48,154,11,548,15,4857,75,4,57,45,45,45,74,54,4577,877);
System.out.println(i1);//[1, 45, 78, 265, 48, 154, 11, 548, 15, 4857, 75, 4, 57, 45, 45, 45, 74, 54, 4577, 877]
Collections.sort(i1);
System.out.println(i1);//[1, 4, 11, 15, 45, 45, 45, 45, 48, 54, 57, 74, 75, 78, 154, 265, 548, 877, 4577, 4857]
ArrayList<Person> l1 = new ArrayList<>();
Person p1=new Person("张三",18);
Person p2=new Person("李四",19);
Person p3=new Person("王五",20);
l1.add(p1);
l1.add(p2);
l1.add(p3);
System.out.println(l1);
Collections.sort(l1);
System.out.println(l1);
}
}
package collectionstext;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/*
java.util.Collections
static <T> void sort(List<T> list, Comparator<? super T> c)
comperable和comperor的区别
comperable(自己,this)和别人(参数)比较,自己需要实现Comperable接口,重写比较规则comperTo方法
comperor,相当于找一个第三方的裁判来比较两个人
*/
public class Demo02 {
public static void main(String[] args) {
ArrayList<Integer> i1 = new ArrayList<>();
Collections.addAll(i1,1,45,78,265,48,154,11,548,15,4857,75,4,57,45,45,45,74,54,4577,877);
Collections.sort(i1, new Comparator<Integer>() {
//重写比较的规则
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;//升序
}
});
System.out.println(i1);
ArrayList<Student> i2 = new ArrayList<>();
i2.add(new Student("张三",18));
i2.add(new Student("李四",19));
i2.add(new Student("王五",20));
i2.add(new Student("a王五",20));
System.out.println(i2);
Collections.sort(i2, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int re =o1.getAge()-o2.getAge();//按照年龄升序
if(re==0){
re =o1.getName().charAt(0)-o2.getName().charAt(0);
}
return re;
}
});
System.out.println(i2);
}
}
/*
package collectionstext;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
*/
Map集合
- java.util.Map<K,V>,K - 由此地图维护的键的类型 ,V - 映射值的类型
- Collection中元素的集合是孤立的,单身,向集合中存储元素采用逐个存贮的方式
- Map集合中元素成对存在,每一个元素由键和值两部分组成,通过键可以找到相应的值
- Collection称为单列集合,Map称为双列集合
常用方法
package maptext;
import java.util.HashMap;
import java.util.Map;
/*
java.util .Map<K,V>集合
Map集合的特点
1.Map集合是一个双列集合,一个元素包含两个值(一个是key,一个是value)
2.Map集合中的K和V的元素类型可以相同,也可以不相同
3.Map中的K是不允许重复的,V是可以重复的
4.Map集合中的元素K与V是一一对应的
java.util.HashMap<K,V>集合,Implemented Map <K,V>接口
HashMap<K,V>集合的特点
1.HashMap的底层是哈希表,查询速度非常快
JDK1.8之前,数组+单向链表
JDK1.8及之后,数组+单向链表、红黑树(当链表长度大于8)
2.HashMap是无序的,存储顺序可能与取出顺序不相同
java.util.LinkedHashMap<K,V> 集合,extends HashMap<K,V>
LinkedHashMap<K,V> 集合的特点
1.LinkedHashMap底层是链表+哈希表(保证迭代顺序)
2.LinkedHashMap集合是一个有序的集合,存储顺序可能与取出顺序一直
*/
public class Demo01 {
public static void main(String[] args) {
show01();
show02();
show03();
show04();
}
/*
containsKey(Object key) 如果此映射包含指定键的映射,则返回 true ,不包含返回false
*/
private static void show04() {
Map<String, Integer> h4 = new HashMap<>();
h4.put("孙悟空",146);
h4.put("猪八戒",178);
h4.put("沙和尚",189);
System.out.println(h4.containsKey("孙悟空"));//true
System.out.println(h4.containsKey("唐僧"));//false
}
/*
public V get(Object key) 通过键,来获取相应的值
返回值
K存在,返回对应的V值
K不存在,返回null
*/
private static void show03() {
Map<String, Integer> h3 = new HashMap<>();
h3.put("孙悟空",146);
h3.put("猪八戒",178);
h3.put("沙和尚",189);
Integer v3 = h3.get("孙悟空");
// System.out.println(v3);//146
Integer v2 = h3.remove("唐僧");
// System.out.println(v2);//null
}
/*
public V remove(Object key) 把指定键对应的键值删除,返回被删除的键值
返回值
K存在,V返回被删除得知
K不存在,返回空
*/
private static void show02() {
//创建Map对象
Map<String, Integer> h2 = new HashMap<>();
h2.put("孙悟空",146);
h2.put("猪八戒",178);
h2.put("沙和尚",189);
// System.out.println(h2);//{沙和尚=189, 孙悟空=146, 猪八戒=178}
Integer v1 = h2.remove("猪八戒");
// System.out.println(v1);//178
// System.out.println(h2);//{沙和尚=189, 孙悟空=146}
Integer v2 = h2.remove("唐僧");
// System.out.println(v2);//null
// System.out.println(h2);//{沙和尚=189, 孙悟空=146}
}
/*
public V put(K key, V value) 将指定的值与值,放在集合中。
返回值,V
存储键值对的时候,key不重复,返回值为null
存储键值对的时候,key重复,会使用新的V来代替旧的V,并返回被替换的V
*/
private static void show01() {
//创建Map对象,可以使用多态
Map<String, String> h1 = new HashMap<>();
String v1 = h1.put("张三", "李四");
// System.out.println(v1);//null
String v2 = h1.put("张三", "王五");
//System.out.println(v2);//李四
// System.out.println(h1);//{张三=王五}
h1.put("无情","铁手");
h1.put("夺命","追风");
h1.put("你好","追风");
// System.out.println(h1);//{张三=王五, 你好=追风, 夺命=追风, 无情=铁手}
}
}
package maptext;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
Map集合的第一种遍历方式,通过键找值的方式
Map集合中的方法,keySet() 方法
实现步骤
1.使用Map集合中的方法keySet() 方法,把所有集合中的所有key元素存储到一个,set集合中
2.遍历set集合,获取集合中的每一个key
3.通过Map集合中的get(key),通过key来找到Value
*/
public class Demo02 {
public static void main(String[] args) {
Map<String, Integer> h4 = new HashMap<>();
h4.put("孙悟空",146);
h4.put("猪八戒",178);
h4.put("沙和尚",189);
//1.使用Map集合中的方法keySet() 方法,把所有集合中的所有key元素存储到一个,set集合中
Set<String> s1 = h4.keySet();
//2.遍历set集合,获取集合中的每一个key
Iterator<String> it= s1.iterator();
while (it.hasNext()){
String v=it.next();
Integer integer = h4.get(v);
System.out.println(integer);
}
//使用增强for
for (String v : s1) {
Integer integer = h4.get(v);
System.out.println(integer);
}
}
}
Entry键值对对象
package maptext;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
Map集合遍历的第二种方式,使用Entry对象来遍历
Map集合中的方法
Set<Map.Entry<K,V>> entrySet() 返回此地图中包含的映射的Set视图。
实现步骤
1.使用Map集合中的EntrySet方法,把Map集合中的多个Entry对象取出来,存储到set集合中
2.遍历Set集合,获取每一个Entry对象
3.使用Entry中的方法getKey()和getValue(),获取键与值
*/
public class Demo03 {
public static void main(String[] args) {
Map<String, Integer> h4 = new HashMap<>();
h4.put("孙悟空",146);
h4.put("猪八戒",178);
h4.put("沙和尚",189);
// 1.使用Map集合中的EntrySet方法,把Map集合中的多个Entry对象取出来,存储到set集合中
Set<Map.Entry<String, Integer>> entries = h4.entrySet();
//2.遍历Set集合,获取每一个Entry对象
//使用迭代器
Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
while (iterator.hasNext()){
Map.Entry<String, Integer> en = iterator.next();
//3.使用Entry中的方法getKey()和getValue(),获取键与值
System.out.println(en.getKey()+"====="+en.getValue());
}
for (Map.Entry<String, Integer> en1 : entries) {
System.out.println(en1.getKey()+"====="+en1.getValue());
}
}
}
HashMap存储自定义键值
package maptext;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*
HashMap存储自定义键值
Map集合保证Key是唯一的
作Key的元素那必须重写hashCode和equals方法,以保证key唯一
*/
public class Demo04 {
public static void main(String[] args) {
//show();
show02();
}
/*
HashMap存储自定义键值
key使用Person,必须重写hashCode和equals方法,以保证key唯一
Value使用String类型,可以重复
*/
private static void show02() {
//创建集合
HashMap<Person,String > map = new HashMap<>();
//添加元素
map.put(new Person("女王",18),"英国");
map.put(new Person("秦始皇",18),"秦国");
map.put(new Person("普京",33),"俄罗斯");
map.put(new Person("女王",18),"毛里求斯");
//使用entrySet和增强for
Set<Map.Entry<Person, String>> entries = map.entrySet();
for (Map.Entry<Person, String> entry : entries) {
System.out.println(entry.getKey()+"===="+entry.getValue());
}
}
/*
HashMap存储自定义键值
key为String类,String类重写hashCode和equals方法,因此key唯一
Value使用Person类,同名同龄视为同一个人
*/
private static void show() {
//创建集合
HashMap<String, Person> map = new HashMap<>();
//添加元素
map.put("北京", new Person("张三", 18));
map.put("上海", new Person("李四", 19));
map.put("广州", new Person("王五", 20));
map.put("北京", new Person("张四", 18));
//使用keySet加增强for循环遍历
Set<String> strings = map.keySet();
for (String string : strings) {
System.out.println(string + "===="+map.get(string));
}
}
}
/*
package maptext;
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", 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);
}
}
*/
LinkedHashMap
package maptext;
import java.util.HashMap;
import java.util.LinkedHashMap;
/*
java.util.LinkedHashMap<K,V> extends HashMap<K,V>
哈希表和链表实现的Map接口,具有可预测的迭代次序。顺序可知
底层原理
哈希表+链表(记录存储的顺序)
*/
public class Demo05 {
public static void main(String[] args) {
HashMap<String, String> map= new HashMap<>();
map.put("a","a");
map.put("c","c");
map.put("b","b");
map.put("a","d");
System.out.println(map);//{a=d, b=b, c=c} key不允许重复,无序
LinkedHashMap<String, String> map1 = new LinkedHashMap<>();
map1.put("a","a");
map1.put("c","c");
map1.put("b","b");
map1.put("a","d");
System.out.println(map1);//{a=d, c=c, b=b} key不允许重复,有序
}
}
Hashtable集合
package maptext;
import java.util.HashMap;
import java.util.Hashtable;
/*
java.util.Hashtable<K,V> 集合,implements Map<K,V>,接口
Hashtable底层是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢
HashMap底层是一个哈希表,是一个线程不安全的集合,是多线程集合,速度快
HashMap集合(之前学习的)可以存储,null值和null键
Hashtable集合,不能存储,null值和null键
Hashtable集合与Vector一样,在jdk1.2之后被更先进的 HashMap集合与ArrayList取代
Hashtable集合的子类properties依然活跃
properties集合,是一个唯一与Io流结合的集合
*/
public class Demo06 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("a",null);
map.put(null,"b");
map.put(null,null);
System.out.println(map);//{null=null, a=null}
Hashtable<String, String> table = new Hashtable<>();
table.put("a",null);//NullPointerException
table.put(null,"b");//NullPointerException
table.put(null,null);//NullPointerException
}
}
练习
package maptext;
import java.util.HashMap;
import java.util.Scanner;
public class Text {
public static void main(String[] args) {
//使用Scanner来接收字符串
Scanner scan = new Scanner(System.in);
String s=scan.next();
System.out.println(s);
//创建Map集合,来存储字符和字符的个数
HashMap<Character, Integer> map = new HashMap<>();
char[] chars = s.toCharArray();
//遍历数组,获取每一个字符
for (char aChar : chars) {
//判断key的个数
if(map.containsKey(aChar)){
Integer i = map.get(aChar);
i++;
map.put(aChar,i);
}else{
map.put(aChar,1);
}
}
System.out.println(map);
scan.close();
}
}
JDK9对集合添加的优化
package maptext;
import java.util.List;
/*
JDK9的新特性
LIst接口,Set接口,Map接口,定义了一个新的静态方法of,用于一次性给集合添加元素
使用前提
集合中的数据个数已确定,且不再改变时
注意
of方法只适用于,LIst接口,Set接口,Map接口,不适用于其实现类
of方法的返回值是一个不能改变的集合,集合不能再使用add、put方法对其添加元素,会抛出异常
set接口与map接口不能有重复元素,否则抛出异常
*/
public class Demo07 {
public static void main(String[] args) {
List.of("a","b","a","j");
}
}
推荐阅读
-
java常用集合框架
-
Java 集合(一)
-
1.Java核心API--集合
-
Java集合类汇总
-
Java集合 ——List 接口
-
《易道客》源码剖析之四:页面多次跳转的记忆 博客分类: 易道客 java易道客页面跳转开源框架
-
Java常用类库——国际化程序(Locale,ResourceBundle以及MessageFormat处理动态文本)...
-
form表单的Action.java文件和jsp之间数据传递 博客分类: web框架 strutsjavajspJavaScriptXHTML
-
ssh三大框架代码的自动生成 博客分类: java 自动生成配置文件自动生成代码ssh自动生成三大框架自动生成
-
基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(v6.9.0版) 博客分类: TableGo java数据库自动生成代码零代码编程软件框架