Skip to content

Latest commit

 

History

History
208 lines (183 loc) · 7.86 KB

集合中难测试题.md

File metadata and controls

208 lines (183 loc) · 7.86 KB

1. Collections.sort 与 Arrays.sort的区别和联系

Collections.sort是集合工具类中的方法,根据元素的自然顺序,按照升序排列指定的列表,列表中的所有元素都必须实现Comparable接口。
Arrays.sort是数组工具类中的排序算法,属于快速排序的一种。

2. 请回答Arraylist, LinkedList, HashSet, LinkHashSet, TreeSet, HashMap, LinkedHashMap, TreeMap的底层存储结构

ArrayList数组列表底层存储结构是动态数组。
LinkedList链表底层存储结构是链表。
HashSet,HashMap底层存储结构是哈希表。
TreeSet,TreeMap底层存储结构是红黑树。
LinkedHashSet是在HashSet的基础上维护元素插入顺序,实现原理大概是链表+哈希表
LinkedHashMap是在HashMap的基础上维护元素插入顺序,实现原理大概是链表+哈希表

3. 请编写代码让ArrayList存入10个数据, 再在遍历ArrayList的时候变遍历便删除元素, 同时把删除元素打印出来, 最后打印集合, 请使用两种方式实现

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.ListIterator;

class A {
    public static void main(String[] args) throws InterruptedException {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(15);
        list.add(20);
        list.add(405);
        list.add(22);
        list.add(11);
        list.add(60);
        list.add(504);
        list.add(33);
        list.add(245);
        list.add(302);
        operate1(list);
//        System.out.println(list.get(0));
    }
    static void operate1(ArrayList<Integer> list) throws InterruptedException {
        // for循环
        System.out.println("原数组:"+list);
        Thread.sleep(500);
        System.out.println("for循环正在遍历数组...");
        Thread.sleep(500);
        for (int i = list.size()-1; i >= 0 ; i--) {
            int j = list.get(i);
            list.remove(i);
            System.out.println("已删除"+j);
            Thread.sleep(300);
        }
        System.out.println("遍历完成的数组:"+list);
    }
    static void operate2(ArrayList<Integer> list) throws InterruptedException {
        //迭代器
        //展示正序遍历方法 保留反序遍历
        System.out.println("原数组:"+list);
        Thread.sleep(500);
        System.out.println("迭代器正在遍历数组...");
        Thread.sleep(500);
//        ListIterator<Integer> iterator = list.listIterator(list.size());  反序遍历
        Iterator iterator = list.iterator();
//        ListIterator<Integer> iterator = list.listIterator(list.size());
        while (iterator.hasNext()){     //iterator.hasPrevious()
            System.out.println("已删除"+iterator.next());  //iterator.previous();
            iterator.remove();
            Thread.sleep(300);
        }
        System.out.println("遍历完成的数组:"+list);
    }
}

4. 怎么让一个集合里面的内容填充后, 内容不会再被修改, 请使用HashMap, 提示使用Collections类里的unmodify

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

class A {
    public static void main(String[] args) throws InterruptedException {
        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(1, 200);
        map.put(2, 625);
        map.put(3, 123);
        System.out.println("原映射:"+map);
        Thread.sleep(500);
        Map<Integer, Integer> newMap = Collections.unmodifiableMap(map);
        System.out.println("不可修改映射:"+newMap);
        Thread.sleep(500);
        System.out.println("正在修改...");
        Thread.sleep(500);
        System.out.println("newMap.put(2, 1);");
        Thread.sleep(1000);
        try {
            newMap.put(2, 1);
        } catch (Exception e) {
            throw new UnsupportedOperationException("不支持的操作!修改失败!!!");
        }
    }
}

5. HashMap是如何解决hash碰撞的

解决哈希冲突的方法通常有两种开放寻址法和链表法HashSet解决哈希冲突的方法就是链表法将产生冲突的值存放在一个bucket中再通过equals方法对比内容确定具体的值HashMap也是通过链表法解决哈希冲突的在JDK8之后貌似还用了红黑树来解决链表高度过大的问题HashMap中元素存放的地址区域称为一个bucket(),链表法允许一个bucket存放多个元素或者其他映射首先通过hashCode()方法根据对象内容产生一个整型的哈希值哈希函数的映射是有限的但是对象的状态是无限的因此哈希冲突不可避免当产生哈希冲突时即两个对象的哈希值相同那么根据链表法产生冲突的两个对象会被放在同一个bucket中当map对象被调用时哈希表会根据对象的哈希值去找这个bucket发现这个bucket中有多个元素此时会使用equals方法来判断对象的内容从而确定要找的元素

6. 设计有一个三级HashMap(三个HashMap分别存储)的工厂类, 三级HashMap存储创造对象的本工厂类, 二级HashMap存储空参构造对象, 但是没有赋值, 一级存储赋值后的对象,每个对象的name属性为map的key值, 要求在测试类里使用一级HashMap根据Key值查找对象, 查到返回对象, 如果未查到, 程序进入二级HashMap查找未赋值对象, 如果查到就进行赋值并存入一级HashMap, 未查到对象就进入三级HashMap获取工厂对象来创建未赋值的对象存入二级HashMap, 提示: 可以用循环来判断一级HashMap有没有对象

/**
 * Student对象
 */
public class Student {
    private String name;
    private Integer age;
    private String sex;

    public Student {

    }

    public Integer getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public String getSex() {
        return sex;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
    public String toString() {
        System.out.println("name=" + getName() + ", age=" + getAge() + ", sex=" + getSex());
    }
}
/**
 * 这里写上你的三级存储的工厂类
 */


/**
 * 这里写上你的测试类
 */


7. (放松题) 请使用随意Map集合存入三个省份的地级市名称, 省份随意, 地级市不少于4个, 要求能根据省份名称查找当前你存入的地级市名称

import java.util.*;

class A {
    public static void main(String[] args) {
        HashMap<String, ArrayList<String>> map = new HashMap<>();
        ArrayList<String> city = new ArrayList<>();
        city.add("十堰市");
        city.add("武汉市");
        map.put("湖北省",city);
        map.put("广东省",new ArrayList(Collections.singleton("深圳市"))); //返回一个只包含指定对象的不可变集合
        map.put("香港特别行政区",new ArrayList(Collections.singleton("新界")));
        System.out.println("输入你要查找的省级单位:(目前包括湖北省,广东省,香港特别行政区)");
        Scanner in = new Scanner(System.in);
        String input = in.nextLine();
        switch (input){
            case "湖北省":
                System.out.println("values:");
                System.out.println(map.get("湖北省"));
                break;
            case "广东省":
                System.out.println("values:");
                System.out.println(map.get("广东省"));
                break;
            case "香港特别行政区":
                System.out.println("values:");
                System.out.println(map.get("香港特别行政区"));
            default:
                System.out.println("非法输入!");
        }
    }
}