基础笔记8(一)(collection,迭代,排序)
1,容器,接口以及子接口 collection :
list;set(:hashset);map(:hashmap)
2.接口中的子接口还定义和父接口相同的方法,只是为了实现类更好的可读性。
3.容器的对象移除,通过调用对象的equals()和hashcode()比较来认为是同一根对象:
list.add(new Date(444)); list.remove(new Date(444)); 这样是可以移除对象的。
4.数组和ArrayList的最大区别是增加了扩容(使其不再是固定长度)。
ArryList() { element = new Object[10]; } void add(Object o) { if (size >= element.length) {//扩容;赋值给新数组 Object[] newElement = new Object[size * 2 + 1]; System.arraycopy(element, 0, newElement, 0, element.length); element = newElement; } element[size++] = o; }
5.列表移除元素remove(object o):即把后面的元素往前面移动,如果是最后一个元素,只要置null且--size;(只会删除第一个equals()==ture认为是同一个元素)
6.linkedList:链表,通过首尾节点找到下一个节点。每个节点包括上一个节点 和下一个节点。(可以判断选择首or尾开始来提升查找效率)
7hashmap:底层是数组里面存放包含键值的链表结构的节点,(加入新元素,通过hash获得数组位置,首先判断插入同key覆盖vlalue.然后插入新数据,一个亮点是,新放入的数据放在最前面,原有数据放在节点的next上(后面);【不需常规的思维模式,先判断是否有节点,再遍历插入到最后位置】
8.collection 中 remove contain 中比较对象首先比较hashcode(),然后比较equals()方法 。
【特点】: 1.默认的hashcode是地址,equals比较的是对象地址。(string 有对equals重写使其比较字符;string的toString()调用了hashcode()方法。) 2.hashcode值可能有负数; 3.同时遵循相等的对象拥有相同的hashcode值。 【目的】: hashcode的目的使得对象成为规律分布 【场景】: 对于自定义需要比较认为相等的对象需要对hashcode()和equals()重写。
9.set接口集合,无序不重复。hashset 的底层是hashmap,将元素存放在key中,利用key的不可以重复特性。
private static final Object PRESENT = new Object(); public boolean add(E e) { return map.put(e, PRESENT)==null;
容器的迭代器:(只有hasNext(),next(),remove())
底层:迭代器只是每个不同容器内部类,以提供获得元素方法。
目的:为容器提供统一遍历元素的方法接口
10.AbstractList 的内部类,内部类直接访问外部类中元素方法。利用多态调用的是子类方法
public abstract class AbstractList{
private class Itr implements Iterator<E> {
public boolean hasNext() { return cursor != size(); } public E next() { E next = get(cursor); lastRet = cursor++; return next; public void remove() { if (lastRet == -1) throw new IllegalStateException(); AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount;
remove()不能连续调用。
11.使用增强循环for(:)遍历元素,必须实现iterable接口的iterator() [或者本身是数组];
简化了迭代器的方法调用(但迭代器使用中可以删除对象)。
(一些容器使用迭代器遍历效率比较高,因为有些直接操作硬盘)
public class ArrayListTest<T> implements Iterable<T>{ ... @Override public Iterator<T> iterator() { return new Iterator<T>() { @Override public boolean hasNext() { return false; } @Override public T next() { return null; } @Override public void remove() { } }; }
public static void main(String[] args) { ArrayListTest<String> a = new ArrayListTest<String>(); for(String m:a){ System.out.println(m); }
12.map中检查存再获取有些多余,直接获取判断是否存在
比如:要知道各种物品的数量(物品有id ,name 其他属性)
int[] gs={...}; Map<Integer, Goods> gCountsMap=new HashMap<>(); for(int gId:gs){ //第一种判断存在再取值,再计算 if(!gCountsMap.containsKey(gId)){ Goods g=new Goods; g.add(); gCountsMap.put(gId,g); } gCountsMap.get(gId).add(); //第二种获取存在再判断存在,计算 Goods g=null; if(!null==(g=gCountsMap.get(gId))){ g=new Goods; gCountsMap.put(gId,g); } g.add(); }
排序之冒泡排序
13.冒泡思路:
a.每次两两比较确定一个较大数(或者较小)交换位置,依次比较完整组,得到最大数(或最小数)
b.第二遍类似第一遍得到一个第二大数(或最小数)
c.每一遍的比较次数比上一次都有减少一次
13.1优化以上冒泡排序(已经有序了却重复多余的排序)
(上面的理想的情况是每一遍排序后剩余数据依然是无序,存在一种可能就是数据已经有序或者经过几次排序后,数据变成有序了,任然进行多余的比较)

浙公网安备 33010602011771号