集合基础


容器:数组就是一种容器而且是效率最高的,但是本身不够灵活 容量必须实现定义好
java中集合就是容器

泛型

泛型:一种约束,泛型可以省略判断、审查步骤、可读性更强

public static void main(String[] args) {
    M<String> m = new M<String>();//jdk 1.7以后可以省略后面的泛型
    m.set("黑",0);
    m.set(111,1);//报错,提示不可以使用String以外的类型
    String a = m.get(0);
    String b = m.get(1);//报错
}
class M<E>{//此时E就代表String
    Object[]o = new Object[5];
    public void set (E e,int i){
        o[i]=e;
    }
    public E get (int i){
        return (E)o[i];
    }
}

Collection接口

List接口和Set接口继承了Collection接口
List是有序、可重复容器 即可要通过下标访问元素、可以加入重复元素
Set是无序、不可重复容器

List接口的实现类:ArrayList()、LinkedList()和Vector/CopyOnWriteArrayList;
set接口的实现类: TreeSet(); HashSet();
Map接口的实现类:HashMap(); TreeMap(); HashTable();

Collection接口常用方法:

c.add(“万”);//添加万
c.remove(“万”);//移除 万 也可以写索引:c.remove(0);//删除下标为1的元素
c.size()//集合的个数
c.isEmpty()/判断是否为空/
c.contains(“万”)/是否包含 万/
c.clear();//移除集合内所有元素
list2.addAll(list1);//拿到list1中所有元素加入到list2 结果返回到list2中
list2.removeAll(list1);//删除list1和list2中相同的部分 结果返回到list2中
list2.retainAll(list1);//删除list1和list2中不相同的部分 结果返回到list2中
list1.containsAll(list2)//判断list1中是否包含list2中所有元素

List

ArrayList:

ArrayList底层是用数组来实现存储。特点:查询效率高,增删效率低且线程不安全。一般情况使用
需要频繁增删改的用LinkedList()/需要线程安全的用Vector/CopyOnWriteArrayList

ArrayList常用方法:

list.indexOf(Object o);//返回元素o的下标 如果不存在返回-1
list.lastIndexOf(Object o);//从右往左找到 返回元素o的下标 如果不存在返回-1 这个方法为了防止有重复元素

扩容:

ArrayList长度可以扩充,在长度不够时自动新建一个更长的数组 把原来的元素拷贝过去
List list = new ArrayList(100);//长度为100 不写这个参数 默认为10
ArrayList中所有的删除操作其实都是遍历数组然后通过下标判断,然后将后面的元素通过 System.arraycopy方法搬到前面

在Arraylist的添加操作中,
当数组elementData长度等于下标时新建数组设置长度为原来数组的 1.5 倍,
通过System.arraycopy方法
//把elementData数组的值放到newArray数组中,从elementData的0(第一个0)开始 放到newArray中的0(第二个0)共放elementData.length
System.arraycopy(elementData,0,newArray,0,elementData.length);

LinkedList

LinkedList底层用双向链表实现的存储。特点:查询效率低,增删改效率高,线程不安全。
previous 为上一个 next 为下一个 element 为当前

添加:
第一次添加元素则 第一个元素和最后一个元素都为当前元素:first=node; last=node;
不是第一次添加元素:node.previous=last;node.next=null;last.next=node;last=node;
查:查询第一个元素为:first.next 第二个为: first.next.next ……
可以先比较当前索引与集合中元素数量大小:

Node t = null;
        if (n<=(size>>1)){
            t = first;
            for (int i=0;i<n;i++){
                t=t.next;
            }
        }else {
            t = last;
            for (int i=size-1;i>n;i--){
                t=t.previous;
            }
        }
        Node temp = getNode(n);
        return temp!=null?temp.element:null;

根据索引添加:

public void  add(int index,Object o){
    Node Newnode = new Node(o);
    Node temp = getNode(index);

    if (temp!=null){
        Node up = temp.previous;

        up.next=Newnode;
        Newnode.previous=up;

        Newnode.next=temp;
        temp.previous=Newnode;
    }
    size++;
}

删除:remove 通过索引删除某个元素:

Node temp = getNode(n);
if (temp!=null){
    Node up = getNode(n).previous;//这个元素的上一个
    Node down = getNode(n).next;//这个元素的下一个
if (up!=null){
    up.next=down; //直接跳过当前元素 把上一个元素的next设置成下一个元素
}
if (down!=null){
    down.previous=up;//直接跳过当前元素 把下一个元素的previous设置成上一个元素
}
if (n==0){
    first=down;
}
if (n==size-1){
    last=up;
}
    size--;
}

Map

HashMap

map中的key 键不能够重复,如果重复则会覆盖旧的
是否重复根据equals方法来判断

HashMap底层实现采用了哈希表,是一种非常重要的数据结构
哈希表基本结构是 数组+链表
存储过程:put(key,value)
调用key对象的hashcode()方法得出hashcode哈希码,哈希码通过HashMap的hash()方法计算出对应的哈希值 hash
哈希值 hash 要求在0-数组长度-1 之间 也就是说 hash等于hashcode % 数组长度 (早期的HashTable采用的算法)
后来采用取余方式 : hash值等于hashcode & (数组长度-1) 这个是有个条件:首先约定数组长度必须为2的整数幂
jdk8以后当数组长度大于8时候 链表会转化为红黑树 这样又大大提高了查找效率
假如算出的是15 那么就在 HashMap的Entry[]数组中下标为15的元素的的地方创建一个链表来存储这个元素
链表中有 hash key value next 第二次存放hash为15的元素时 第一个创建的元素的next就是他的hash

取数据:get(key):
1.获得key的hashcode,通过hash()散列算法得到hash值,进而定位到数组的位置。
2.在链表上挨个比较key对象。调用equals()方法,将key对象和链表上所有节点的key对象进行比较,
直到碰到返回true的节点对象为止
3.返回equals()为true的节点对象的value对象
Java中有规定 两个相同的对象即:t.equals(y)为ture时 必须具有相等的hashCode。

TreeMap 一般用于排序,会按照key自增的方式排序 不常用
Comparable接口 需要泛型

HashTable 线程安全,效率低。不允许key或者value为null 方法和hashmap一样 只是这几点不同
HashMap 线程不安全,效率高,允许key或者value为null

HashMap常用方法:

添加方法: m.put(key,value)
获取:m.get(key)
判断是否为空:m.isEmpty()
是否包含key为2的 m.containsKey(2);
是否包含value为four的 m.containsValue(“four”);

Set

Set接口继承于Collection接口 set接口没有顺序不能重复
没有顺序所以要查找的话需要遍历去对比
不能重复所以当新元素添加时与就元素equals()为ture时 不能添加

HashSet

HashSet中的方法和Collection一样 只是不可重复没有顺序
可以说HashSet是简化版的HashMap
可以理解为HashSet添加的元素都是HashMap中的key,再HashMap中key就是不可重复的
TreeSet

TreeSet底层源码中:

public TreeSet(){
this(new TreeMap<E,Object> ()); E就是默认key
}
与 TreeMap一样 自动排序

Iterator迭代器

public static void testIteratorList() {
    List<String> list = new ArrayList<>();
    list.add("a00");
    list.add("v");

    //使用迭代器遍历list
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) { //list.iterator() 获取迭代器 相当于初始化 iterator.hasNext()判断是否有下一个
        String temp = iterator.next();//iterator.next() 即返回当前对象 并且游标也会指向下一个
        System.out.println(temp);
    }
    //如果需要遍历的时候删除元素 建议使用:
    Iterator<String> iterator = list.iterator();
    while(iterator.hasNext()){
        Object obj = iterator.next();
        iterator.remove();
        System.out.println(obj);
    }
}

遍历set的操作和list一样 只有Map有一些不同:

public static void testIteratorMap(){

    Map<Integer,String> map = new HashMap<>();
    map.put(100,"ss");
    map.put(200,"cc");
    map.put(300,"dd");

    //第一种遍历Map方式
    Set<Entry<Integer,String>> ss =map.entrySet();//entrySet实现了Set接口,里面存放的是键值对。一个K对应一个V。
    for (Iterator<Entry<Integer,String>> ite =ss.iterator();ite.hasNext();){
        Entry<Integer,String> temp = ite.next();
        System.out.println(temp.getKey()+":"+temp.getValue());
    }
    //第二种方式
    Set<Integer> keySet = map.keySet();//keySet里面存放了K
    for (Iterator<Integer> iter =keySet.iterator();iter.hasNext();){
        Integer key = iter.next();
        System.out.println(key+":"+map.get(key));
    }

Collections工具类

Collections工具类常用方法

sort(List); //对List内容器按照递增方式排序
shuffle(list);//随机排列list中的元素
reverse(list);//逆序排列
binarySearch(list,“b”));//二分法查找“b” 并返回索引(下标)
测试:

public static void main(String [] args){

    List<String> list = new ArrayList<>();
   for (char a='a';a<'g';a++){
       String s = String.valueOf(a);
      list.add(s);
   }
    System.out.println(list);
    Collections.shuffle(list);//随机排列list中的元素
    System.out.println(list);

    Collections.reverse(list);//逆序排列
    System.out.println(list);

    Collections.sort(list);//按照递增方式排序
    System.out.println(list);

    System.out.println(Collections.binarySearch(list,"a"));//二分法查找“a” 并返回索引(下标)
}

使用容器来存储表格数据:

Map和List结合存储表格:

ORM思想的简单实验:map表示一行数据,多行数据是多个map 将多个map放到一个list中

public static void main(String[] args) {
    Map<String,Object> map = new HashMap<>();
    map.put("ID",1001);
    map.put("姓名","李四");
    map.put("薪资",30000);
    map.put("日期","2021-01-07");

    Map<String,Object> map2 = new HashMap<>();
    map2.put("ID",1002);
    map2.put("姓名","张三");
    map2.put("薪资",3000);
    map2.put("日期","2021-02-07");

    Map<String,Object> map3 = new HashMap<>();
    map3.put("ID",1003);
    map3.put("姓名","王五");
    map3.put("薪资",20000);
    map3.put("日期","2020-08-07");

    List<Map<String,Object>> list = new ArrayList<>();
    list.add(map);
    list.add(map2);
    list.add(map3);
    for (Map<String,Object> m:list
         ) {
        for (String i:m.keySet()
             ) {
            System.out.print(i+":"+m.get(i)+"\t");
        }
        System.out.print("\n");
    }
}

JavaBean和List\Map结合存储表格:

ORM思想的简单实验:javabean表示一行数据,多行数据是多个javabean 将多个javabean放到一个list\map中

class  User{
    private  int id;
    private String name;
    private double salary;
    private String hiredate;

    有参无参构造方法

    set get 方法

    toString 方法
}
public static void main(String[] args) {
    User user1 = new User(1001,"张三",2134,"2021-01-07");
    User user2 = new User(1002,"李四",10000,"2021-12-07");
    User user3 = new User(1003,"王五",2134,"2021-08-07");

   // 与List结合:
    List<User> list = new ArrayList<>();
    list.add(user1);
    list.add(user2);
    list.add(user3);

    for (Iterator<User> u=list.iterator();u.hasNext();){
        User a = u.next();
        System.out.println(a);
    }

    // 与Map结合:
    Map<Integer,User> map = new HashMap<>();
    map.put(1001,user1);
    map.put(1002,user2);
    map.put(1003,user3);

    Set<Entry<Integer, User>> set = map.entrySet();
    for (Iterator<Entry<Integer,User>> e = set.iterator();e.hasNext();){
        Entry<Integer,User> en = e.next();
        System.out.println(en);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值