简介
- 本文是2021/04/23整理的笔记
- 赘述可能有点多,还请各位朋友耐心阅读
- 本人的内容和答案不一定是最好最正确的,欢迎各位朋友评论区指正改进
ArrayList
ForEach删除容易出错
- 增强for循环不能删除东西,会出现ConcurrentModification 并发修改异常
@Test
public void testForEachDel(){
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
for (Integer integer : list) {
System.out.println("integer = " + integer);
boolean remove = list.remove(new Integer(20));
System.out.println("remove = " + remove);
}
System.out.println(list);
}
迭代器使用list.remove也不能删除,会报错
@Test
public void testIteratorDel(){
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
Integer next = iterator.next();
System.out.println("next = " + next);
boolean remove = list.remove(new Integer(20));
System.out.println("remove = " + remove);
}
}
迭代器remove可以删除 iterator.remove
@Test
public void testIteratorRemove(){
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
Integer next = iterator.next();
System.out.println("next = " + next);
iterator.remove();
}
System.out.println("list = " + list);
}
LinkedList
常用方法1
- add(E e) 将指定元素添加到此列表的结尾。
- addFirst(E e) 将指定元素插入此列表的开头。
- addLast(E e) 将指定元素添加到此列表的结尾
- element() 获取但不移除此列表的头(第一个元素)
- getFirst() 返回此列表的第一个元素
- getLast() 返回此列表的最后一个元素
- peek() 获取但不移除此列表的头(第一个元素)。
- peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null
- peekLast() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null
- poll() 获取并移除此列表的头(第一个元素)
- pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null
- pollLast() 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null
- push(E e) 将元素推入此列表所表示的堆栈
- pop() 从此列表所表示的堆栈处弹出一个元素
- remove(int index) 移除此列表中指定位置处的元素。
- removeFirst() 移除并返回此列表的第一个元素。
@Test
public void testAdd(){
LinkedList<String> list = new LinkedList<>();
list.add("刘备");
list.add("关羽");
list.addFirst("诸葛亮");
list.addLast("赵云");
list.offer("孙尚香");
list.offerFirst("黄忠");
list.offerLast("马超");
System.out.println("list = " + list);
System.out.println("list.removeLast() = " + list.removeLast());
System.out.println("=====================");
System.out.println("list = " + list);
}
常用方法2
- removeFirstOccurrence 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)
- removeLastOccurrence从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)
- toArray 返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组。
@Test
public void testRemove(){
LinkedList<String> list = new LinkedList<>();
list.add("刘备");
list.add("关羽");
list.add("关羽");
list.add("张飞");
list.add("关羽");
list.add("关羽");
list.add("关羽");
System.out.println("list = " + list);
boolean b = list.removeLastOccurrence("关羽");
System.out.println("b = " + b);
System.out.println("=====================");
System.out.println("list = " + list);
String[] array = list.toArray(new String[0]);
for (String s : array) {
System.out.println("s = " + s);
}
}
}
Stack
常用方法
- push(E item) 把项压入堆栈顶部。
- pop() 移除堆栈顶部的对象,并作为此函数的值返回该对象
- peek()查看堆栈顶部的对象,但不从堆栈中移除它。
- empty() 测试堆栈是否为空
- search(Object o)返回对象在堆栈中的位置,以 1 为基数。如果对象 o 是堆栈中的一个项,此方法返回距堆栈顶部最近的出现位置到堆栈顶部的距离;堆栈中最顶部项的距离为 1。使用 equals 方法比较 o 与堆栈中的项。
@Test
public void testPush(){
Stack<String> stack = new Stack<String>();
stack.push("刘备");
stack.push("关羽");
stack.push("张飞");
System.out.println("stack = " + stack);
System.out.println("stack.empty() = " + stack.empty());
System.out.println("stack.search(\"刘备\") = " + stack.search("刘备"));
System.out.println("stack.search(\"关羽\") = " + stack.search("关羽"));
System.out.println("stack.search(\"张飞\") = " + stack.search("张飞"));
}
ArrayList 和 LinkedList 的区别
存储结构
- ArrayList 的底层采用的是以数组为基础存储
- LinkedList 的底层采用的是链表存储的.
性能
- ArrayList:增加元素,删除元素,修改元素性能比 LinkedList 慢,读取数据速度快.
- 链表:增加元素,删除元素,修改元素性能比 ArrayList 快.读取速度慢.
Set集合
- 描述:无序不可重复的集合。
默认初始容量 加载因子
HashSet
add不能添加重复元素
@Test
public void testAdd(){
HashSet<String> set = new HashSet<>();
set.add("刘备");
set.add("关羽");
set.add("张飞");
System.out.println("set = " + set);
}
add有大坑
- Set中不能添加重复元素,但是如下情况添加的元素并不是重复元素,添加的元素都是新new出来的对象。
@Test
public void testAddPerson(){
HashSet<Person> set = new HashSet<>();
set.add(new Person("孙权",26));
set.add(new Person("孙权",26));
set.add(new Person("孙权",26));
set.add(new Person("周瑜",23));
set.add(new Person("周瑜",23));
}
remove删除()和ArrayList的情况类似
- ForEach删除容易出错
- 迭代器使用list.remove也不能删除,会报错
- 迭代器remove可以删除 iterator.remove
不可重复的集合在调用add方法添加元素时,JVM会调用compareTo方法
重写equals和HashCode方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return getAge() == person.getAge() &&
Objects.equals(getName(), person.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getAge());
}
内部比较器
@Test
public void testAddPerson2(){
TreeSet<Person> set = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int i = o1.getAge() - o2.getAge();
int j = o1.getName().compareTo(o2.getName());
return i == 0?j:i;
}
});
set.add(new Person("a",50));
set.add(new Person("b",20));
set.add(new Person("c",20));
System.out.println("set = " + set);
}
外部比较器
@Override
public int compareTo(Person o) {
int i = this.getAge() - o.getAge();
int j = getName().compareTo(o.getName());
return i == 0?j:i;
}
其他一些需要注意的点
- 先比较HashCode 如果不同 则通过equals比较
- 不能使用普通for循环遍历set集合,set集合是无序的。
- forEach也不能用set.remove删除