Collection接口
- List:有顺序,元素可以重复
- Set:没有顺序,元素不可以重复
Set内部有一个专门排序的算法- 所谓的无序不等于随机
- 所谓的无序指的是没有按照添加的先后顺序,其实内部是做了内部排序的
顺序指的是添加的先后顺序
List
List:数据时有顺序的,数据可以重复
ArrayList集合:内部结构是数组。比较适合做高频率的查找、遍历
LinkedList集合:双向链表。比较适合做高频率的新增和删除
//List<String> list = new LinkedList<>();
LinkedList<String> list = new LinkedList<>();
//添加数据
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//创建对象时用的是多态
//父类对象---->子类引用
//创建出来的对象只能调用父类和子类都有的方法
//在集合头部添加
list.addFirest("z");
//在集合尾部添加
list.addLast("x");
//删除集合第一个元素
list.removeFirst();
//删除集合最后一个元素
list.removeLast();
//根据下标索引获取指定位置的元素
list.get(int index)
List集合的遍历
List<String> list = new ArrayList<>();
1.for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
2.foreach循环
for (String s: list) {
System.out.println(s);
}
3.迭代器
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String s = iterator.next();
System.out.println(s);
}
Set
Set集合如何确保数据的不重复
->保证数据类型的类要重写hashCode和equals方法
实例如下:
Set<Person> set = new HashSet<>();
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));
System.out.println(set);
上述代码为使数据不重复在Person类中重写hashCode和equals方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (!name.equals(person.name))
return false;
return id.equals(person.id);
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + id.hashCode();
return result;
}
TreeSet
排序规则:要排序的对象的类必须实现Comparable接口
Set<Person> tree = new TreeSet<>();
tree.add(new Person("张岳",1001));
tree.add(new Person("李四",1010));
tree.add(new Person("费四",1003));
在Person类中实现Comparable接口,并重写compareTo()方法
@Override
public int compareTo(Person p) {
if (this.id > p.id) {
return -1;
}
if (this.id.equals(p.id)) {
return 0;
}
return 1;
}
LinkedHashSet
由于LinkedHashSet的底层是哈希表和链表,所以它与其它的Set集合的区别就是,LinkedHashSet是有序的。使得其在添加数据的同时维护数据的添加顺序,效率比HashSet略低
- 哈希表:保证集合的唯一性特点
- 链表:保证有序
Set集合的遍历
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(4);
set.add(15);
set.add(38);
//增加for循环
for (Integer integer: set) {
System.out.println(integer);
}
//迭代器
Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()){
Integer s = iterator.next();
System.out.println(s);
}
比较接口
Comparable接口:自然排序,排序规则是固定的
Comparator接口:临时排序
Comparable的compareTo(T)方法只有1个参数,.
Comparator接口的compare(T o1, T o2)方法有两个参数
Map接口
- 存储对值K-V key-value
- key不能重复,value是可以重复的
- 没有顺序(添加的先后顺序)
HashMap内部存储结构:
jdk1.7之前:链表 + 二叉树
jdk1.7及其之后:链表 + 数组 + 红黑树
Map<String, String> map = new HashMap<>();
map.put("1001","张岳");
map.put("1002","赵红兵");
map.put("1003","小北京");
map.put("1004","李四");
map.put("1005","张浩然");
//获取values()值 姓名
System.out.println(map.values());
//获取keySet() ID
System.out.println(map.keySet());
Hashtable和HashMap的区别
- Hashtable是线程同步的,线程安全 HashMap是线程异步的,线程不安全
- HashMap的key是可以为null的,Hashtable是不可以为null
Properties:属性
Properties是Hashtable的子类,更多地是用来操作属性文件
迭代中删除元素
public class Ch13 {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("tom");
names.add("lucy");
names.add("lucy");
names.add("lucy");
names.add("jerry");
for (int i = 0; i < names.size(); i++) {
if(Objects.equals(names.get(i),"lucy")){
names.remove(i);
// 1.回调指针
i--;
}
if("lucy".equals(names.get(i))){
}
}
// 2.逆序遍历
for (int i = names.size() - 1; i >= 0; i--) {
if(Objects.equals(names.get(i),"lucy")){
names.remove(i);
}
}
// 3.使用迭代器(推荐)万无一失
Iterator<String> iterator = names.iterator();
while(iterator.hasNext()) {
String s = iterator.next();
if(Objects.equals(s,"lucy")){
iterator.remove();
}
}
// 4.增强for循环
for (String s : names) {
if(Objects.equals(s,"lucy")){
names.remove(names.indexOf(s));
}
}
System.out.println(names);
}
}
其他的集合
- LinkedHashMap,在HashMap的基础上维护了一个双向链表。
- TreeMap:天然支持排序
- Collections:Collections是一个工具类
- 线程安全问题:
- 迭代器是依赖于集合而存在,在判断成功以后,集合中新增了元素,
- 迭代器不知道,所以就报错。
- 解决:
- 1.迭代器遍历元素,迭代器删除元素
- 2.普通for循环遍历,集合删除
public class Ch15 {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("tom");
names.add("lucy");
names.add("lucy");
names.add("lucy");
names.add("jerry");
for (String s : names) {
if (Objects.equals(s, "lucy")) {
names.add(s);
}
}
}
}