集合
之前已经学了数组,特点:有序,同一类型,创建后长度不可更改,增删改查的操作非常麻烦。
集合:跟数组一样,是个容器,可以放置任何数据类型,增删改查很方便,可以重复
所有的集合类都在java.util包下面,集合是存储大量对象数据的容器,这个容器有大小
对象数据的类型: Object
集合体系:
1.Collection集合
特点: Collection集合提供一种存储空间可变的存储模型,存储的数据容量可以随着数据的改变而改变
概念: Collecton是单列集合的顶层接口,它表示一组对象,这些对象都称之为Collection集合元素
2.List集合
list集合概念:
List集合是一种可重复且有顺序的集合,用户可以精确的通过每个元素下标去精确地访问或操作元素.
list特点: 1.有索引 2.内容可以重复 3.存取有序
List集合方法:
方法名 | 描述 |
---|---|
add(Object) | 末尾追加一个元素 |
add(index,Object) | 在指定下标位置添加一个元素,元素往后移动 |
addAll(Collection) | 末尾追加集合,集合类型一致 |
remove(index) | 删除指定下标元素 |
remove(object) | 删除对应元素 |
set(index,obj) | 修改指定下标元素 |
get(index) | 获取指定下标元素 |
clear() | 清空集合 |
toArray() | 将集合转换为数组 |
size() | 集合大小(元素的个数) |
1.ArrayList集合
ArrayList集合: 是一种类数组集合,与数组相似,长度可变,且存储的元素为对象元素
格式: List list = new ArrayList(); 初始长度为10,集合的大小就是元素个数
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ArrayListDemo {
public static void main(String[] args) {
// 创建数组集合
List list = new ArrayList();
//添加数据
list.add("张三");
list.add(18);
list.add(0,"lisi");
list.add(55.4);
//添加集合
list.addAll(list);
//在指定下标添加集合
list.addAll(1,list);
//修改集合元素
list.set(0, "李四");
//删除元素
list.remove("lisi");
//通过get的方法获取到集合中的元素
//元素的最大个数就是大小
for (int i = 0; i < list.size(); i++) {
//因为集合中存储Object类型,所以使用任何单一类型都可能出错
// String name = (String) list.get(i);
// System.out.println(name);
//通过get下标的方式获取集合元素
Object obj = list.get(i);
System.out.println(obj);
}
Object[] obj = list.toArray();
System.out.println(Arrays.toString(obj));
}
}
遍历集合
- 普通遍历,使用get(下标)方式遍历 2采用foreach循环的方式遍历 3.采用Iterator的方式遍历集合
Iterator迭代器: 是一个用于遍历集合数据的工具,承接来自于集合的数据,用于遍历,本身不存储数据
方法: hasNext()判断迭代器中是否有下一个元素,有返回true 没有就返回false
next()将找到的这个元素获取,获取后指针向下移动
public class ArrayListDemo2 {
public static void main(String[] args) {
// 创建数组集合
List list = new ArrayList();
//添加数据
list.add("张三");
list.add(18);
list.add(0,"lisi");
list.add(55.4);
//通过get的方法获取到集合中的元素
//元素的最大个数就是大小
for (int i = 0; i < list.size(); i++) {
//通过get下标的方式获取集合元素
Object obj = list.get(i);
System.out.println(obj);
}
//2.使用foreach方法遍历集合
System.out.println();
for (Object obj : list) {
System.out.print(obj+", ");
}
System.out.println("\n");
//3.采用集合中的Iterator迭代器遍历元素
Iterator iter = list.iterator();
//hasNext()判断是否有下一个元素
while(iter.hasNext()) {
//next()将元素取出
System.out.print(iter.next()+", ");
}
}
}
2.LinkedList集合
概念: LinkedList集合是一种链表式集合.方便于添加,删除集合元素
实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量的首尾操作方法
方法名 | 描述 |
---|---|
addFirst(obj) | 在集合开头添加元素 |
addLast(obj) | 在集合末尾添加数据 |
getFirst() | 返回集合中的第一个元素 |
getLast() | 返回集合末尾元素 |
removeFirst() | 移除并返回集合第一个元素 |
removeLast() | 移除并返回集合最后一个元素 |
public class LinkedListDemo {
public static void main(String[] args) {
// 创建链式集合
LinkedList list = new LinkedList();
//添加元素
list.add("张三");
list.addFirst("张飞");
list.addFirst("张辽");
list.addLast("张良");
list.removeFirst(); //删除第一个元素
System.out.println("最后一个元素为:"+list.getLast());
list.clear(); //清空集合
for (Object obj : list) {
System.out.print(obj+", ");
}
}
}
3.Set集合
Set集合同样继承与Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能的扩展,只是比Collection集合更加的严格,Set集合与List不同,Set集合中的元素无序且唯一.
Set集合中有多个子类实现类,常用HashSet,TreeSet集合
HashSet集合
hashSet根据对象的哈希值来确定元素在集合中是否存在,因此具有良好的存取和查找性能.
我们学习这个集合常用于HashMap集合使用
方法名 | 描述 |
---|---|
add(obj) | 添加元素 |
remove(obj) | 通过元素删除 |
size() | 获取到集合大小 |
public class HashSetDemo {
public static void main(String[] args) {
//创建一个无序且唯一的Set集合,实现类为HashSet
Set set = new HashSet();
//添加元素
set.add("张三");
set.add("李四");
List list = new ArrayList();
//添加数据
list.add("张三丰");
list.add("王飞");
set.addAll(list);
//删除元素
set.remove("张三丰");
//遍历
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next()+",");
}
System.out.println("集合大小为:"+set.size());
}
}
TreeSet集合
HashSet只能保存和获取查找元素,无法对元素进行有效的排序,这时候需要使用treeSet集合对set集合元素排序
ThreeSet集合是一个有序且唯一的集合,可以按照一定的规则进行排序,具体排序取决构造方法中放入的排序规则,默认构造方法为数字的自然排序
public class TreeSetDemo {
public static void main(String[] args) {
//创建TreeSet集合,对内容进行自然排序
//默认排序主要针对于Integer类型排序
Set set = new TreeSet();
//存储元素
set.add(5);
set.add(8);
set.add(18);
set.add(9);
set.add(12);
set.add(7);
//遍历集合,输出元素以自然顺序输出
for (Object obj : set) {
System.out.print(obj+", ");
}
}
}
对对象排序,需要排序规则Comparable进行对象的自然排序
步骤: 1准备实体类
2.需要自然排序的对象所在类实现Comparable接口,重写排序方法
3.直接遍历对应对象的集合,自然排序
//实现自然排序接口
public class Student implements Comparable<Student> {
private String name;
private int age;
private String address;
public Student(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
}
//重写排序方法
@Override
public int compareTo(Student stu) {
//按年龄从小到大排序
int num = this.age - stu.age;
return num;
}
}
public class TreeSetDemo1 {
public static void main(String[] args) {
//<>表示集合只能存储某种类型
Set<Student> set = new TreeSet<>();
set.add(new Student("张三", 18, "广东广州"));
set.add(new Student("李四", 20, "广东广州"));
set.add(new Student("王五", 19, "广东广州"));
set.add(new Student("赵六", 21, "广东广州"));
for (Student stu : set) {
System.out.println(stu.toString());
}
}
}
在需要在使用时对对象排序
//实现自然排序接口
public class Student {
private String name;
private int age;
private String address;
public Student(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
public class TreeSetDemo1 {
public static void main(String[] args) {
//<>表示集合只能存储某种类型
//在TreeSet集合中重写排序,这种只需要在要使用时才排序
Set<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.getAge()-s2.getAge();
}
});
set.add(new Student("张三", 18, "广东广州"));
set.add(new Student("李四", 20, "广东广州"));
set.add(new Student("王五", 19, "广东广州"));
set.add(new Student("赵六", 21, "广东广州"));
for (Student stu : set) {
System.out.println(stu.toString());
}
}
}
泛型集合
在集合之后使用<>表示为泛型, 其中<类型>类型表示为,集合只能规范的存储指定类型,解决线程不安全的
格式: 集合<类型> 集合名 = new 集合<>();
如: List<Student> list = new ArrayList<>(); 表示为list集合中只能存储Student集合,遍历的时候不用强转
Vector集合
ArrayList可以说是Vector的翻版,区别在于Vector 是线程安全的,ArrayList是线程不安全的,但是Vector是一个较老的集合,具有诸多缺点,效率较低不建议使用
且当泛型集合出现后,有效的解决了线程不安全得问题
案例介绍
按照斗地主的规则,完成洗牌发牌的动作。
具体规则:
使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。
案例分析
准备牌:
牌可以设计为一个ArrayList,每个字符串为一张牌。
每张牌由花色数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。
牌由Collections类的shuffle方法进行随机排序。
发牌
将每个人以及底牌设计为ArrayList,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。
看牌
直接打印每个集合。
import java.util.ArrayList;
import java.util.Collections;
public class Poker_Collections_shuffle_1 {
public static void main(String[] args) {
/*创建一副扑克*/
String[] num = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
String[] color = {"黑桃", "红桃", "梅花", "方块"};
ArrayList<String> poker = new ArrayList<>();
for (String s1 : num) {
for (String s2 : color) {
poker.add(s2.concat(s1)); // concat() ==> 连接两个字符串
}
}
poker.add("小王");
poker.add("大王");
/*洗牌*/
Collections.shuffle(poker); // Collections.shuffle() ==> 随机置换
/*发牌*/
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> myself = new ArrayList<>();
ArrayList<String> dipai = new ArrayList<>();
for (int i = 0; i < poker.size(); i++) {
if (i >= poker.size() - 3) {
dipai.add(poker.get(i));
} else if (i%3 == 0) {
player1.add(poker.get(i));
} else if (i%3 == 1) {
player2.add(poker.get(i));
} else {
myself.add(poker.get(i));
}
}
/*看牌*/
System.out.println("Player1的牌为: " + player1);
System.out.println("Player2的牌为: " + player2);
System.out.println("myself 的牌为: " + myself);
System.out.println("底牌: " + dipai);
}
}
Map集合
map集合的概念
Map集合是一种键值对集合,使用key对应value形式的双列集合,一般key中使用Set集合类型,Value使用Collection集合
Map集合特点
1.键值对应关系 2.一个键对应一个值 3.键是一个set集合,无序且唯一,可以有null或""但只能有一个
4.元素存取是无序(因为map集合是通过key获取到value)
Map集合的子类实现类: HashMap HashTable TeeMapp
格式: Map<K,V> 集合名称 = new HashMap<>();
方法: put(k,v) 添加元素
putAll(Map) 添加一个集合元素
remove(k) 删除元素
containsKey(key) 判断key是否存在
keySet() 获取到所有的键
isEmpty() 判断是否为null
get(key) 通过key获取到对应的value
public class HashMapDemo {
public static void main(String[] args) {
//创建一个Map集合
Map<String, String> map = new HashMap<String, String>();
//添加元素
map.put("CN", "中华人民共和国");
map.put("USA", "美利坚合众国");
map.put("JP", "小本子");
map.put("PK", "巴基斯坦");
Map<String, String> map1 = new HashMap<String, String>();
map1.put("JP", "日本");
map1.put("FR", "法国");
map1.put(null, "超级帝国");
map.putAll(map1);
//获取到JP键对应的值
System.out.println("JP对应的国家是:"+map.get("JP"));
//遍历集合,先获取键集合 keySet()
for(String key: map.keySet()) {
System.out.println(key+"===="+map.get(key));
}
}
}
注意: 使用put方法时,若指定的key在集合中不存在,把指定的key存入到集合中,若指定的key在集合中存在,替换原来的值
Map集合中存储List集合
public class HashMapDemo1 {
public static void main(String[] args) {
//创建一个Map集合,一般map集合中key使用String,值根据需求使用不同类型
//一个省(key),存储对应的多个市(List<String>)
Map<String, List<String>> map = new HashMap<>();
//准备list集合内容
List<String> city1 = new ArrayList<String>();
city1.add("广州市");
city1.add("深圳市");
city1.add("佛山市");
city1.add("珠海市");
List<String> city2 = new ArrayList<String>();
city2.add("南宁市");
city2.add("北海市");
city2.add("桂林市");
city2.add("柳州市");
List<String> city3 = new ArrayList<String>();
city3.add("台北市");
city3.add("高雄市");
city3.add("台南市");
city3.add("台中市");
//添加到集合
map.put("广东省", city1);
map.put("台湾省", city3);
map.put("广西省", city2);
//遍历集合,先获取键集合 keySet()
Set<String> set = map.keySet();
for(String key: set) {
System.out.print(key+"对应的市有:");
//通过循环遍历value值(list集合)
List<String> list = map.get(key);
for (String city : list) {
System.out.print(city+",");
}
System.out.println();
}
}
}
键盘录入一个字符串,要求统计字符串中每个字符出现的次数
如: ajsgfhkas 在控制台输出 a2 j1 s2 …
1.输入字符串
2.建立Map<String,Integer>
3.循环字符串每个字符,charAt(i)获取到每个字符
4.以当前获取的字符,作为key去获取value
如果: value==null 表示为第一次找到该字符, 字符—1
value!=null 表示为至少第二次 , value++ 重新放入map集合中
public class CharMapDemo {
public static void main(String[] args) {
/*
* 键盘录入一个字符串,要求统计字符串中每个字符出现的次数
* 如: ajsgfhkas 在控制台输出 a2 j1 s2 ....
* 1.输入字符串
* 2.建立Map<String,Integer>
* 3.循环字符串每个字符,charAt(i)获取到每个字符
* 4.以当前获取的字符,作为key去获取value
* 如果: value==null 表示为第一次找到该字符, 字符---1
* value!=null 表示为至少第二次 , value++ 重新放入map集合中
*/
Scanner in = new Scanner(System.in);
System.out.println("请输入一个字符串");
String str = in.next();
//建立一个字符对应次数的map集合
Map<Character, Integer> map = new HashMap<>();
//遍历字符串,得到每一个字符
for (int i = 0; i < str.length(); i++) {
char key = str.charAt(i); //根据对应的下标返回字符
//以当前字符作为key去获取value值
Integer val = map.get(key);
if(val==null) {
map.put(key, 1);
}else {
val++;
map.put(key, val);
}
}
//遍历集合,获取到字符和对应的次数
Set<Character> set = map.keySet();
for (Character key : set) {
System.out.print(key+""+map.get(key)+", ");
}
}
}
Collections集合工具类
概念:
是针对于集合操作的工具类,工具类中封装了很多对于集合操作的静态方法
常用方法:
方法名 | 描述 |
---|---|
max(集合) | 获取到集合中的最大值 |
min(集合) | 获取到集合中的最小值 |
replaceAll(集合,原有值,新的值) | 使用新的值去替换集合中原有值 |
sort(集合) | 对集合自然排序 |
reverse(集合) | 反转集合 |
shuffle(集合) | 打乱集合顺序 |
public class CollectionsDemo {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<Integer>();
//添加元素
nums.add(50);
nums.add(26);
nums.add(38);
nums.add(27);
nums.add(19);
//获取到集合中的最大值
System.out.println("集合最大值:"+Collections.max(nums));
//获取到集合最小值
System.out.println("集合最小值:"+Collections.min(nums));
//集合排序
Collections.sort(nums);
System.out.println("自然排序的集合元素:"+nums);
Collections.reverse(nums);
System.out.println("反转后的集合:"+nums);
//乱序
Collections.shuffle(nums);
System.out.println("乱序后的集合:"+nums);
//替换内容
Collections.replaceAll(nums, 50, 66);
System.out.println("替换后的集合:"+nums);
}
}