Collection接口-集合的顶层
Collection体系介绍
方法 | 解释 |
---|---|
public boolean add( E e ) | 添加一个元素(对象) |
public boolean remove( E e ) | 删除一个元素(对象) |
public boolean contains( Object obj ) | 判断是否包含 |
public boolean isEmpty() | 判断是否为空 |
public void clear() | 清空 |
public int size() | 返回集合长度 |
//这个祖宗是个接口,要使用它的方法需要创建它实现类的对象
Collection<String> coll = new ArrayList<>();
//add(元素):将元素添加到coll
coll.add("aaa");
coll.add("bbb");
System.out.println(coll);
//删除”bbb“
coll.remove("bbb");
System.out.println(coll);
//判断”bbb“是否存在
System.out.println(coll.contains("bbb"));
//判断是否为空
System.out.println(coll.isEmpty());
//查看当前长度(元素个数)
System.out.println(coll.size());
//清空
coll.clear();
System.out.println(coll);
// 输出结果:
[aaa, bbb]
[aaa]
false
false
1
[]
注意点:
-
Collection是一个接口,不能创建他的对象,使用他的方法时,应该创建他实现类的对象。
-
contain的底层是使用equals实现,当引用数据类型使用contain判断,默认比较的是地址值,应当根据需求重写equals方法(这里字符串类型已经写好了,默认就不需要重写)
-
集合的数据类型是无序的,无法用常规的for循环遍历,但是Java提供了其他遍历方法:迭代器、增强for循环、lambda表达式
迭代器、增强for循环、lambda表达式
迭代器:可以理解为一个指针
增强for循环:只适用单列集合与数组
lambda表达式:forEach()
迭代器方法 | 解释 |
---|---|
hasNext(元素) | 若元素在集合存在,返回true |
next() | 1.获取当前指针元素,2.指针向下移一位 |
remove() | 删除元素 |
Collection<String> coll = new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
//迭代器对象的指针不会复位,若需要重新遍历,需要获取一个新的Iterator对象
//迭代器遍历时,不能像集合那样增删
//调用iterator()方法,返回迭代器对象
Iterator<String> it = coll.iterator();
//hasNext():当前指针指向若有元素,返回true,没有返回false
while (it.hasNext()){
//next():方法执行两个操作:1.获取元素,2.向下一位移动指针
String str = it.next();
System.out.println(str);
}
//增强for循环
//第三方元素s逐个接收coll每一个遍历得到的元素,并进行打印
for(String s:coll){
System.out.println(s);
}
//没用lambda表达式之前的遍历,不换行输出
coll.forEach(new Consumer<String>() {
//底层是for循环遍历得到每一个元素,交给accept方法
@Override
public void accept(String s) {
System.out.print(s);
}
});
//lambda表达式:forEach()
coll.forEach(s -> System.out.println(s));
// 输出结果:
aaa
bbb
ccc
aaa
bbb
ccc
aaabbbccc
aaa
bbb
ccc
迭代器 - 注意事项
- 迭代器指针不会复位,执行重新遍历需要重新获取Iterator对象
- 循环中只能使用一个next()方法,否则会报错:NoSuchElementException
- 使用迭代器遍历时,不要使用集合的增加、删除等方法,避免并发操作异常
- 当指针指向已无元素,若继续执行next()则报错:NoSuchElementException
增强for循环 - 注意事项
- 增强for循环的原理是利用一个第三方元素逐个接收集合元素
- 如果只进行遍历操作,可使用增强for循环
lambda表达式 - 注意事项
- lambda表达式适用于简化函数式编程(函数式接口)
- 如果只进行遍历操作,可使用lambda表达式
List列表 - 分支1
List列表特点
- 有序:取出元素的顺序跟存入元素时的顺序一样
- 有索引:能通过索引查找/操作对应元素
- 可重复:允许存在相同元素,相同元素的索引不同
- ListIterator :列表迭代器,相对于Iterator,多了插入操作
List<String> list = new ArrayList<>();
//没有参数默认使用Collection的方法,尾插
list.add("aaa");
list.add("ccc");
list.add("ddd");
System.out.println(list);
//带索引,使用List自己的add方法
list.add(1,"bbb");
System.out.println(list);
//没有索引默认使用Collection的方法,根据元素删除元素
//有索引使用List自己的remove()方法,根据索引删除元素
list.remove(1);
System.out.println(list);
//set:List分支有序,可使用索引位置插入元素
list.set(0,"bbb");
System.out.println(list);
//get:List分支有序,可使用索引获取对应元素
String get1=list.get(2);
System.out.println(get1);
// 输出结果:
[aaa, ccc, ddd]
[aaa, bbb, ccc, ddd]
[aaa, ccc, ddd]
[bbb, ccc, ddd]
ddd
注意事项:
- 方法重载时,优先调用形参与实参一致的方法
- 对于一个Integer类型的List,remove(1)会优先调用List的remove()方法
- 如果要调用Collection的remove,要变成包装类:Integer i = Integer.ValueOf(1) -> remove(1)
- 遍历方式选择:遍历过程需要删除元素(默认迭代器)、遍历过程中需要添加元素(列表迭代器)、单纯遍历(增强for、lambda)、需要进行其他操作(普通for)
Set集合 - 分支2
Set集合特点
- 无序:取出元素的顺序跟存入元素时的顺序可能不一样
- 无索引:不能通过索引查找/操作对应元素,不能用普通for循环遍历
- 不重复:不允许存在相同元素,可以用此特点去除重复元素
TreeSet
- TreeSet的底层实现结构是红黑树,不需要重写hashCode和equals方法()
- 特别点是可以有序的,存入自动升序,按照ASCII的数字顺序排列
- 存自己定义的数据类型,需要在类型中定义排序规则,否则报错
- 方式一:数据类实现comparable接口,重写compareTO方法
- 方式二:方式一也不满足需求,在创建TreeSet时候指定比较器(new comparator) o1是当前要添加的元素,o2是树已经有的元素
遍历:
TreeSet<Integer> ts = new TreeSet<>();
ts.add(4);
ts.add(2);
ts.add(1);
ts.add(5);
ts.add(3);
//不重复,自动去重
ts.add(5);
System.out.println(ts);
//三种遍历 迭代器
Iterator it = ts.iterator();
while (it.hasNext()){
int i = (int)it.next();
System.out.print(i);
}
//增强for
System.out.println();
for (Integer t : ts) {
System.out.print(t);
}
//lambda
System.out.println();
ts.forEach(integer -> System.out.print(integer));
// 输出结果:
[1, 2, 3, 4, 5]
12345
12345
12345
排序规则:
//比较器 Comparator
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int i = o1.length()-o2.length();
//如果长度相同,默认排序
i = i==0 ? o1.compareTo(o2) : i;
//长度不同,长度排序
return i;
}
});
ts.add("abf");
ts.add("d");
ts.add("cd");
ts.add("ca");
System.out.println(ts);
//默认的首字母
TreeSet<String> ts1= new TreeSet<>();
ts1.add("abf");
ts1.add("d");
ts1.add("cd");
ts1.add("ca");
System.out.println(ts1);
// 输出结果:
[d, ca, cd, abf] //长度排序-长度相同-字母排序
[abf, ca, cd, d] //首字母排序
Map接口 - 双列集合
Map体系介绍
特点
- 双列集合一次需要存入一对数据(键值对、Entry对象)
- 键值一一对应,键不可重复,值可以重复
- TreeMap是排序的,HashMap不是
方法 | 解释 |
---|---|
get(key) | 根据key获取value的值 |
put(key,vaule) | 添加键值对,若键存在,则更新值,返回旧值 |
remove(key) | 根据键,删除整个键值对,返回value的值 |
boolean containsKey(key) | 判断集合是否包含指定key |
boolean containsValue(value) | 判断集合是否包含指定value |
boolean isEmpty() | 判断集合是否为空 |
clear() | 清除集合中的所有元素 |
int size() | 返回集合长度(键值对个数) |
keySet() | 把集合的key抽取生成一个set(一般用于遍历) |
entrySet() | 把集合的键值对抽取生成一个Set,Set类型为entry对象(键值对) |
Map<String,String> map = new HashMap<>();
map.put("和味道","6");
map.put("康师傅","4");
map.put("公仔面","6");
map.put("炒面王","5");
//遍历方式一:键查值
// 增强for
Set<String> key = map.keySet();
for (String s : key) {
String value = map.get(s);
System.out.println(s+"->"+value);
}
//迭代器
Iterator<String> it = key.iterator();
while (it.hasNext()){
String key1 = it.next();
String value1 = map.get(key1);
System.out.println(key1+"=>"+value1);
}
//lambda
key.forEach(keys -> System.out.println(keys+"_>"+map.get(keys)));
//返回被删除键值对的值
String s = map.remove("和味道");
System.out.println("删了和味道后,返回了:"+s);
//遍历方式二:键值对(增强for实现)
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> entry : entries) {
String key2 = entry.getKey();
String value2 = entry.getValue();
System.out.println(key2+"=>>"+value2);
}
//和味道已经被删了,找i不到,返回false
System.out.println(map.containsKey("和味道"));
//遍历方式三:lambda
map.forEach((keys,values)-> System.out.println(keys+"==>>"+values));
// 输出结果:
公仔面->6
炒面王->5
和味道->6
康师傅->4
公仔面=>6
炒面王=>5
和味道=>6
康师傅=>4
公仔面_>6
炒面王_>5
和味道_>6
康师傅_>4
删了和味道后,返回了:6
公仔面=>>6
炒面王=>>5
康师傅=>>4
false
公仔面==>>6
炒面王==>>5
康师傅==>>4