15 集合
集合
集合与数组的区别
- 数组的长度是固定的 , 集合的长度是可变的
- 数组中既可以存储基本数据类型 , 也可以存储引用数据类型 , 而集合中只能存储引用数据类型(包装类)
Collection和Collections的区别
- Collection : 单列集合的根接口
- Collections : 集合的工具类
集合结构图
虚线为接口 , 实线为类
Collection
操作元素
boolean add(E e) //添加
boolean remove(Object obj) //移除
void clear() //清空
boolean contains(Object obj) //是否包含
boolean isEmpty() //是否为空
int size() //获得集合的长度
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo1 {
public static void main(String[] args) {
Collection<Object> cl = new ArrayList<Object>();
cl.add("hello");//boolean
cl.add(new Object());
cl.add(new int[] {1,2,3,4,5,6,7});
cl.add(13);
System.out.println(cl.size());
System.out.println(cl);
System.out.println(cl.contains("hello"));
System.out.println(cl.remove("hello"));//boolean
System.out.println(cl);
cl.clear();
System.out.println(cl);
System.out.println(cl.isEmpty());
System.out.println(cl.size());
}
}
操作集合
boolean addAll(Collection c) //添加所有
boolean removeAll(Collection c) //移除所有(凡是参数中包含的内容都会被移除掉)
boolean containsAll(Collection c) //是否全部包含
boolean retainAll(Collection c) //取交集
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo2 {
public static void main(String[] args) {
Collection<String> cc = new ArrayList<String>();
cc.add("三国演义");
cc.add("水浒传");
cc.add("红楼梦");
cc.add("西游记");
cc.add("西厢记");
Collection<String> cc2 = new ArrayList<String>();
cc2.add("三国演义");
cc2.add("水浒传");
cc2.add("红楼梦");
cc2.add("西游记");
cc2.add("西厢记");
cc.addAll(cc2);
cc2.add("西游记");
System.out.println(cc);
System.out.println(cc.contains(cc2));
cc.removeAll(cc2);
System.out.println(cc);
System.out.println(cc.retainAll(cc2));
/**
* 取交集,
* 如果此 collection 由于调用而发生更改则返回 true,
* 用谁调用交集存在哪个集合中
*/
}
}
遍历
Object[] toArray() //把集合转成数组,可以实现集合的遍历
Iterator iterator() //得到一个迭代器的对象
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo3 {
public static void main(String[] args) {
Collection<String> cc = new ArrayList<String>();
cc.add("三国演义");
cc.add("水浒传");
cc.add("红楼梦");
cc.add("西游记");
cc.add("西厢记");
Object[] obj = cc.toArray();
for (int i = 0; i < obj.length; i++) {
Object o1 = obj[i];
String s1 =String.valueOf(o1);
System.out.println(s1);
}
//迭代器
Iterator<String> it = cc.iterator();
//hashNext():判断集合中是否还有下一个元素
//next():取出集合中的下一个元素
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
List
- List : 有序的 ( 可以根据索引操作元素 ) , 元素是可以重复的
常用方法
void add(int index,E element) //插入
E remove(int index) //把指定索引的值移除掉
E get(int index) //索取指定索引对应的元素
E set(int index,E element) //替换
ListIterator lisIterator() //获取ListIterator对象,用于迭代
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo4 {
public static void main(String[] args) {
String string = "小明,29,男;小红,20,女;小张,22,男";
String[] sp1 = string.split(";");
Collection<Person> cc = new ArrayList<Person>();
for (int i = 0; i < sp1.length; i++) {
String[] sp2 = sp1[i].split(",");
Person person = new Person(sp2[0], Integer.parseInt(sp2[1]), sp2[2]);
cc.add(person);
}
Iterator<Person> iterator = cc.iterator();
while(iterator.hasNext()) {
Person per = iterator.next();
System.out.println(per);
}
}
}
class Person{
private String name;
private int age;
private String sex;
public Person() {
super();
}
public Person(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
List遍历
四种遍历方式 :
- 转数组
- Iterator迭代器
- for循环
- ListIterator
public class ListDemo1 {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
Person p1 = new Person("张三",18,'男');
Person p2 = new Person("李四",37,'女');
Person p3 = new Person("王五",38,'男');
list.add(p1);
list.add(p2);
list.add(p3);
//1. 调用toString
Object[] array = list.toArray();
for(int i=0;i<array.length;i++) {
System.out.println(array[i]);
}
System.out.println("-------");
//2. iterator
Iterator<Person> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
System.out.println("-------");
//3 for
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
}
System.out.println("-------");
// listIterator
ListIterator<Person> it2 = list.listIterator();
while(it2.hasNext()) {
System.out.println(it2.next());
}
}
}
class Person{
String name;
int age;
char gender;
public Person() {
}
public Person(String name, int age, char gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
}
List去重
import java.util.ArrayList;
import java.util.List;
public class ListDemo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("大乔");
list.add("小乔");
list.add("二乔");
list.add("大乔");
list.add("大乔");
list.add("大乔");
list.add("二乔");
list.add("大乔");
list.add("小乔");
list.add("大乔");
System.out.println(list);
//选择思想
for (int i = 0; i < list.size() - 1; i++) {
for (int j = i + 1; j < list.size(); j++) {
if (list.get(i).equals(list.get(j))) {
list.remove(j);
j--;
}
}
}
System.out.println(list);
//contains();
List<String> list2 = new ArrayList<String>();
for (int i = 0; i < list.size(); i++) {
if (!list2.contains(list.get(i))) {
list2.add(list.get(i));
}
}
System.out.println(list2);
}
}
ArrayList和LinkedList的区别
LinkedList中特有的方法
addFirst/addLast //添加头/添加尾
getFirst/getLast //获取头/获取尾
removeFirst/removeLast //移除头/移除尾
public class ListDemo1 {
public static void main(String[] args) {
LinkedList<String> ll = new LinkedList<String>();
ll.add("hello");
ll.add("world");
ll.add("php");
ll.add("phyton");
ll.add("scala");
ll.addFirst("java");
System.out.println(ll);
System.out.println(ll.removeFirst());
System.out.println(ll.removeFirst());
System.out.println(ll.removeFirst());
System.out.println(ll.removeFirst());
System.out.println(ll.removeFirst());
System.out.println(ll.removeFirst());
}
}
增强for循环(主要用于数组集合的遍历)
格式 :
for(数据类型 变量名:数组名/集合名){
}
//变量名:集合中的每一个元素
Collection集合的遍历 :
- toArray
- Iterator
- foreach
List集合的遍历 :
- toArray
- Iterator
- for循环+get
- ListIterator
- foreach
public class ForDemo1 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("hello");
al.add("world");
al.add("php");
al.add("phyton");
al.add("scala");
for (String string : al) {
System.out.println(string);
}
}
}
可变参数
用途 :
定义方法时不知道该定义多少个参数
格式 :
修饰符 返回值类型 方法名(数据类型...变量名){
}
注意事项 :
- 这里的变量其实是一个数组
- 如果一个方法有可变参数 , 并且有多个参数 , 那么 , 可变参数必须是最后一个
- 一个方法中最多只能有一个可变参数
public class ArrayToListDemo1 {
public static void main(String[] args) {
getSum(10,20,20,30,40,50,60,12);
}
public static void getSum(int b,int ...a) {
int sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
System.out.println(sum);
}
}
集合和数组的相互转换
- 数组转集合
static List<T> 集合名 = Arrays.asList(T...t);
- 集合转数组
Object toArray();
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ArrayToListDemo2 {
public static void main(String[] args) {
List<Integer> as = Arrays.asList(12,13,45,65,8,7,9);
//使用Arrays.asList 得到的集合是一个只读的集合,不能进行add/remove的操作
ArrayList<Integer> al = new ArrayList<>(as);
al.add(50);
System.out.println(al);
}
}
Set
特点 :
Set中的元素是无序的 ( 不能使用索引操作元素 ) , 元素不可重复
Collection :
- List ( l ) : 有序的 , 元素可重复
- ArrayList
- LinkedList
- Set ( l ) : 无序的 ( 不能使用索引操作元素 ) , 元素不可重复
- HashSet : 无法保证存入和取出的顺序
- LinkedHashSet : 可以保证存入和取出的顺序 ( 链表实现 )
- TreeSet : 有序的 ( 可以对元素排序 )
- HashSet : 无法保证存入和取出的顺序
不可重复性 :
-
是由hashCode和equals方法保证的
-
存放元素的时候 , 先求出元素的hashCode ,
- 如果集合中没有这样的hashCode值 , 说明该元素在集合中不存在 , 可以存放 ;
- 如果集合中有这样的hashCode值 , 再比较equals :
- 如果为true , 集合中已经存在该元素 , 则不存放 ;
- 如果为false , 则可以存放
import java.util.HashSet;
public class SetDemo1 {
public static void main(String[] args) {
HashSet<Student> hs = new HashSet<Student>();
hs.add(new Student("张帆", 24));
hs.add(new Student("张帆", 24));
hs.add(new Student("张帆", 24));
hs.add(new Student("大聪明", 22));
hs.add(new Student("大聪明", 22));
hs.add(new Student("大聪明", 22));
System.out.println(hs);
}
}
class Student {
String name;
int age;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
}
//生成10个不重复的1-20之间的随机数
import java.util.HashSet;
import java.util.Random;
public class SetDemo2 {
public static void main(String[] args) {
Random r = new Random();
HashSet<Integer> hs = new HashSet<Integer>();
while (hs.size() < 10) {
hs.add(r.nextInt(20)+1);
}
System.out.println("随机输入的十个数:" + hs);
}
}
Map
概述 : key-value组成的双列数据集合
- 以key为主 , 寻找value也需要key
- map集合所有的操作都跟key有关
- map中key不允许重复 key是唯一的 但是值可以重复
- 一个key只能对应一个值 但是一个值可以对应多个key
- HashMap:key不能重复,但是可以为null,不能保证key存入和取出的顺序
- LinkedHashMap: 可以保证key存入和取出的顺序
- 如果key相同,value会覆盖 TreeMap
方法 :
V put(K key,V value) //添加元素,返回值是该key上一次对应的value,如果上一次没有值,返回null
V remove(Objectkey) //移除key对应的键值对
void clear() //清空map
boolean containsKey(Object key) //是否包含key
boolean containsValue(Object value) //是否包含value
boolean isEmpty() //是否为空(长度是否为0)
int size() //键值对的个数
public class MapDemo1 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("西游记", "吴承恩");
map.put("水浒传", "施耐庵");
map.put("三国演义", "罗贯中");
map.put("红楼梦", "曹雪芹");
map.put("诛仙", "萧鼎");
map.put("天龙八部", "金庸");
map.put("红楼梦", "高鹗");
System.out.println(map);
map.remove("诛仙");
System.out.println(map);
System.out.println(map.containsKey("诛仙"));
System.out.println(map.containsValue("罗贯中"));
// map.clear();
System.out.println(map.isEmpty());
System.out.println(map.size());
}
}
遍历 :
keySet //获取所有的key
entrySet //获得所有的键值对
values //获取所有的值
public class MapDemo2 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("科比", "小飞侠");
map.put("麦迪", "T-mac");
map.put("詹姆斯", "大猩猩");
map.put("奥尼尔", "大鲨鱼");
map.put("姚明", "小巨人");
map.put("加内特", "狼人");
Set<String> ks1 = map.keySet();
for (String s : ks1) {
System.out.println(s+"--"+map.get(s));
}
System.out.println("===========================");
Set<Entry<String, String>> set = map.entrySet();
for (Entry<String, String> entry : set) {
System.out.println(entry.getKey()+"--"+entry.getValue());
}
}
}
/**
* 成龙,10000;李冰冰,20000;李连杰,30000;成龙,2000;李连杰,10000;李冰冰,2000 求出每个明星捐款次 * 数和捐款总额
*/
import java.util.HashMap;
public class MapDemo5 {
public static void main(String[] args) {
String s = "成龙,10000;李冰冰,20000;李连杰,30000;成龙,2000;李连杰,10000;李冰冰,2000";
HashMap<String, Star> hm = new HashMap<String, Star>();
String[] sp = s.split(";");
for (int i = 0; i < sp.length; i++) {
String[] sp2 = sp[i].split(",");
//getOrDefault() 拿着键去集合里面取值,如果有值直接取出;如果没值就返回一个默认值
Star st = hm.getOrDefault(sp2[0], new Star());
int money = st.getMoney();
int count = st.getCount();
money += Integer.parseInt(sp2[1]);
count++;
st.setMoney(money);
st.setCount(count);
hm.put(sp2[0], st);
}
System.out.println(hm);
}
}
class Star {
String name;
int money;
int count;
public Star() {
super();
// TODO Auto-generated constructor stub
}
public Star(String name, int money, int count) {
super();
this.name = name;
this.money = money;
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
@Override
public String toString() {
return "捐款金额:" + money + ", 捐款次数:" + count;
}
}