java学习笔记——集合类型

Set,List,Map

Set,List,Map是Java中提供的几种专门用于存储对象集合的数据结构,它们都是接口,有各自的实现类,它们都有一个共同的祖先(基类)Collection.

之所以在Java中不使用对象数组来存储对象,是因为对象 数组有几个弊端:
1、数组一经建立,它的容量就已经确定了,容易出现数组下标越界异常,即使能扩容也会因为转移数据消耗大量机器的性能
2、对象数组若不进行初始化赋值,存储在其中的会是默认的NULL类型,很容易造成空指针异常。因为数组的length属性返回
的不是数组中所存的对象的数量,而是数组的容量。
3、数组进行插入删除操作要移动大量元素,时间复杂度较高。

1.List

  • List有三种实现类,ArrayList,LinkedList和Vector
  • List中文名叫做有序集合(也称序列)。它有几个特点:‘
  • 1、可以精确访问和控制列表中每个位置的插入位置,和数组一样有随机读取的优点
  • 2、序列中允许有重复的元素,。。。。。
  • 3、可以存储多个null
  • 4、有序:元素的插入顺序和按index从小到大遍历的顺序一致
1.1 基本操作:

插入: add(int index, Object element)
删除:remove(int Index) 清空:clear() //继承自Collection
按位序查找:get(int index)
按值查找:indexOf(Object o) lastIndexOf(Object o)
修改:set(int index, E element)
判空:isEmpty() //继承自Collection
子序列:subList(int fromIndex, int toIndex) //左闭右开
表长:size() //继承自Collection

1.2 遍历操作:

主要有四种主要的遍历方式:
1.使用迭代器Iterator(继承自Collection的方法)

       Iterator iter =  list.iterator();
       while(iter.hasNext()){
           Object obj = iter.next();
           System.out.println(obj);
       }
       
       for(  Iterator itr =  list.iterator();itr.hasNext();){
           Object obj = itr.next();//在使用迭代器迭代的时候  在一个循环中  next方法只能在一处调用
           System.out.println(obj);
       }

2.使用for循环和索引

       for(int i = 0 ; i < list.size();i++){
            Object obj = list.get(i);
           System.out.println(obj);
       }

3.使用foreach

       for(Object obj : list){
           System.out.println(obj);
       }

4.使用列表迭代器 (本类的)

        // 获取列表迭代器
       ListIterator iterator =  list.listIterator();
       // 遍历同时天剑
        while(iterator.hasNext()){
            Object obj = iterator.next();
            // 当遇到元素为world的时候  给列表追加元素spring
            if(obj.equals("world")){
                iterator.add("spring");
                iterator.previous();//是的指针指向前一个元素
            }
            System.out.println(obj);
        }

若使用Iterator可能会出现并发修改异常:ConcurrentModificationException
原因是Iterator不能在遍历的同时修改原集合对象的元素

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("hello");
        list.add("world");
        list.add("java");
        Iterator iter =  list.iterator();
        while(iter.hasNext()){
            Object obj = iter.next();
            String str = (String) obj;
            if(str.equals("world")){
                list.add("hadoop");//这里会引起异常
            }
        }
    }

ListIterator可以在遍历的同时修改原集合对象

        ListIterator iterator2 =  list.listIterator();
        while(iterator2.hasNext()){
            Object obj = iterator2.next();
            if(obj.equals("hello")){
                iterator2.set("mybatis");
                iterator2.previous();

            }else{
                System.out.println(obj);
            }
        }

 

2.ArrayList和LinkedList和Vector

  1. ArrayList的底层是一个动态数组,查询快,增删慢,每次扩容扩大为原先容量的1.5倍可以用索引随机访问List中任一元素
  2. LinkedList底层采用双向链表实现,查询慢,增删慢,可以直接访问列表的开头和结尾,其它位置需要逐个遍历。添加元素采用
    头插法和尾插法。
  3. Vector相对前两者的优点是线程安全,但效率不高,底层也是可变数组,扩容是变为原始容量的两倍

3.Set集合

特点:

  1. 不包含重复元素的集合
  2. 最多只能有一个null值
  3. 没有索引,只能通过迭代器和增强for进行遍历
  4. set集合是无序的(无序指的是set集合中的元素的添加顺序和迭代顺序不一致)
3.1 HashSet

特点:

  1. 底层的数据结构是哈希表
  2. 实现不同步
  3. 对集合的迭代顺序不做任何保证,也就是说保存的顺序和获取的顺序是不一致的
  4. 没有带索引的方法,只能使用增强for和迭代器进行遍历
  5. 不能包含重复元素
  6. 可以存储null 但是只能存一个
    HashSet如何保证元素的唯一性
    1.根据对象的哈希值计算存储位置:
    如果当前位置没有元素则直接存入,如果有则进入第二步
    2.当前元素和计算所得位置的所有元素进行哈希值的比较
    如果哈希值不同,则直接存储
    如果哈希值相同,则进入第三步
    3.通过equals方法比较元素的内容
    如果内容不同则直接进行存储,如果内容相同,则认为元素重复,不存储
    简单来说,元素的重复性就是哈希值和equals结果相与

所以:对于存入hashSet集合中对象,都必须重写hashCode 和equals方法,以保证元素的唯一性

什么是哈希表
哈希表属于一种数据结构,jdk8以前哈希表采用数组和链表来实现,
jdk8以后哈希表采用数组,链表和红黑树来实现,当链表的长度超过一定值时,就会将链表转换成红黑树

3.2 LinkedHashSet
  • 是Set接口的哈希表和链表的实现,元素是有序的;
  • 采用双向链表保证了元素是有序的,也就是说元素的存储顺序和迭代顺序是一致的
  • 采用哈希表保证元素的唯一性
3.3TreeSet
  • 基于TreeMap实现
  • 可以对其中的元素进行排序。排序方式:自然排序 定制排序
  • 此实现不同步
  • 若要在TreeSet中存放自定义类的对象,要么实现Comparable接口,要么创建一个比较器(实现Comparator)

4.Map

  • 将键映射到值的对象
  • Map不能包含重复的键
  • 每个键可以映射到最多一个值,一个值可以被多个键所映射
4.1 基本方法
put(K key, V value)`  将指定的值与该映射中的指定键相关联(可选操作)
isEmpty()
keySet()  返回以Map中键值构成的Set对象
get(Object key)  返回到指定键所映射的值,或 `null
`containsKey(Object key)` 
containsValue(Object value)
`entrySet()`  返回Map中键值构成的`Set<Map.Entry<K,V>>对象
replace(K key, V value)
size()  返回Map中键值映射的数量
values()` 返回Map中值所构成Collection
4.2 Map的两种遍历方式
//通过keySet()和get()来遍历
Set<String> keySet = map.keySet();
        for(String key :keySet){
            //根据键获取值
            String value = map.get(key);
            System.out.println(key+"---"+value);
//获取键值对集合来访问
      Set<Map.Entry<String,String>> entrySet =  map.entrySet();
      for(Map.Entry<String,String> entry : entrySet){
          //entry代表一对键值对  分别获取键和值
          String key = entry.getKey();
          String value = entry.getValue();
          System.out.println(key +"---" + value);
      }
4.3 HashMap
  • 允许使用null键和null值,null键只能有一个,它是不同步
  • 不保证映射的顺序
  • 所有的value构成的集合是Coollection 无序的 是可以重复的
  • 所有的key构成的集合是set集合 是无序 不可以重复 (key是一个自定义对象 那么此时类必须重写hashcode和equals方法)
  • 一个key和一个value构成一个entry
  • 所有的entry构成的集合是Set 无序的 是不可重复的
  • HashMap中判断key是否唯一的标准和HashSet判断元素是否唯一的方式是一样

Map的默认容量是2的4次方 16,最大容量 2的30次方,默认加载因子 0.75,红黑树的节点数<=6 则转化为链表

4.4 HashTable
  • HashMap类大致相当于Hashtable ,但Hashtable是同步的,且不允许NULL
4.5 TreeMap

基于红黑树实现 可以实现对元素的自然排序和定制排序 此实现不是同步的
对于存入TreeMap中的键 如果是自定义类型 则必须实现Comparable并实现compareTo方法
需要在创建TreeMap对象的时候 传入一个比较器对象

5.集合的工具类Collections

//都是静态方法
sort(List<T> list)  //根据其元素的自然顺序对指定的列表进行排序。
reverse(List<?> list)  //反转指定列表中元素的顺序。
shuffle(List<?> list)  //使用默认的随机源随机排列指定的列表。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
文件上传是Web开发中常见的功能之一,Java中也提供了多种方式来实现文件上传。其中,一种常用的方式是通过Apache的commons-fileupload组件来实现文件上传。 以下是实现文件上传的步骤: 1.在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> ``` 2.在前端页面中添加文件上传表单: ```html <form method="post" enctype="multipart/form-data" action="upload"> <input type="file" name="file"> <input type="submit" value="Upload"> </form> ``` 3.在后台Java代码中处理上传文件: ```java // 创建一个DiskFileItemFactory对象,用于解析上传的文件 DiskFileItemFactory factory = new DiskFileItemFactory(); // 设置缓冲区大小,如果上传的文件大于缓冲区大小,则先将文件保存到临时文件中,再进行处理 factory.setSizeThreshold(1024 * 1024); // 创建一个ServletFileUpload对象,用于解析上传的文件 ServletFileUpload upload = new ServletFileUpload(factory); // 设置上传文件的大小限制,这里设置为10MB upload.setFileSizeMax(10 * 1024 * 1024); // 解析上传的文件,得到一个FileItem的List集合 List<FileItem> items = upload.parseRequest(request); // 遍历FileItem的List集合,处理上传的文件 for (FileItem item : items) { // 判断当前FileItem是否为上传的文件 if (!item.isFormField()) { // 获取上传文件的文件名 String fileName = item.getName(); // 创建一个File对象,用于保存上传的文件 File file = new File("D:/uploads/" + fileName); // 将上传的文件保存到指定的目录中 item.write(file); } } ``` 以上代码中,首先创建了一个DiskFileItemFactory对象,用于解析上传的文件。然后设置了缓冲区大小和上传文件的大小限制。接着创建一个ServletFileUpload对象,用于解析上传的文件。最后遍历FileItem的List集合,判断当前FileItem是否为上传的文件,如果是,则获取文件名,创建一个File对象,将上传的文件保存到指定的目录中。 4.文件上传完成后,可以给用户一个提示信息,例如: ```java response.getWriter().write("File uploaded successfully!"); ``` 以上就是使用Apache的commons-fileupload组件实现文件上传的步骤。需要注意的是,文件上传可能会带来安全隐患,因此在处理上传的文件时,需要进行严格的校验和过滤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值