Java中集合常考面试题总结

目录

一、集合有哪些体系,不同的集合的特性和存储原理是什么?

二、Map中的集合有哪些,线程安全的集合有哪些?

三、HashMap、HashTable、ConcurrentHashMap集合的区别?

四、遍历、迭代集合的方式有哪些?

对于Map集合的遍历方式常用的有以下三种:

五、Java中集合常用的排序方法有哪些?


一、集合有哪些体系,不同的集合的特性和存储原理是什么?

在Java中,集合的体系主要分为以下几种:

1. List(列表):按照元素的插入顺序进行存储,可以允许存储重复元素。
   - ArrayList:基于动态数组实现,支持随机访问,增删操作效率较低。
   - LinkedList:基于双向链表实现,支持快速的插入和删除操作,但访问效率较低。

2. Set(集合):不允许存储重复元素,没有顺序要求。
   - HashSet:基于哈希表实现,插入和查找元素的速度较快,不保证顺序。
   - TreeSet:基于红黑树实现,元素按照自然顺序进行排序或使用自定义的Comparator。

3. Queue(队列):按照先进先出(FIFO)的原则进行操作。
   - LinkedList:可作为队列使用。
   - PriorityQueue:基于优先级堆实现,元素按照优先级进行排序。

4. Map(映射):存储键值对形式的元素,键不允许重复。
   - HashMap:基于哈希表实现,键值对无序存储,查找速度较快。
   - TreeMap:基于红黑树实现,按照键的自然顺序或自定义顺序存储。

不同集合的特性和存储原理如下:
- ArrayList:内部使用动态数组实现,通过数组索引可以快速访问元素,适用于随机访问。添加和删除操作需要移动元素,效率较低。
- LinkedList:内部使用双向链表实现,可以快速进行插入和删除操作,但访问元素需要遍历链表,效率较低。
- HashSet:基于哈希表实现,在添加和查找元素时,通过计算哈希值定位元素存储位置,插入和查找的效率较高。不保证元素的顺序。
- TreeSet:基于红黑树实现,保持元素有序,按照自然顺序或自定义顺序进行存储。插入和查找的效率较高。
- PriorityQueue:基于优先级堆实现,按照元素的优先级进行存储,可以快速获取最高优先级的元素。
- HashMap:基于哈希表实现,通过键的哈希值定位存储位置,插入和查找的效率较高,不保证元素的顺序。
- TreeMap:基于红黑树实现,按照键的顺序进行存储,可以自定义顺序,插入和查找的效率较高。

二、Map中的集合有哪些,线程安全的集合有哪些?

在Java中,常见的Map集合有以下几种:

1. HashMap: 使用哈希表实现,键值对无序存储,插入和查找的效率很高。不保证线程安全。
2. TreeMap: 基于红黑树实现,按照键的顺序进行存储,可以自定义顺序。不保证线程安全。
3. LinkedHashMap: 内部使用哈希表和双向链表实现,可以保持插入顺序或访问顺序。不保证线程安全。
4. ConcurrentHashMap: 使用分段锁(Segment)实现,将整个Map分为多个部分,每个部分独立加锁,允许多线程同时访问不同的部分,提高并发性能。线程安全。
5. Hashtable: 使用内部锁(synchronized)实现,对操作进行同步控制,线程安全,但效率相对较低。
6. WeakHashMap: 具有弱键的特性,当键不再被其它对象引用时,可能会被垃圾回收器回收。不保证线程安全。

线程安全的集合主要有以下几种:
1. ConcurrentHashMap:在多线程环境下保证并发安全,性能较高。
2. Hashtable:使用内部锁来实现线程安全,但性能相对较低,较少使用。
3. CopyOnWriteArrayList:支持并发读取、写入操作,通过复制整个数组来实现写入的线程安全,适合读多写少的场景。
4. CopyOnWriteArraySet:基于CopyOnWriteArrayList实现,线程安全的Set集合。
5. ConcurrentLinkedQueue:基于链表实现的线程安全队列,在多线程环境下可以高效地进行插入、删除操作。
6. ConcurrentSkipListMap:基于跳表实现的线程安全的有序Map,支持高并发访问。

这些线程安全的集合提供了在多线程环境下使用的安全性,但在某些场景下会导致一些额外的开销,因此需要根据具体需求进行选择。如果只涉及到单线程操作,不需要线程安全性,那么非线程安全的集合会更加高效。

三、HashMap、HashTable、ConcurrentHashMap集合的区别?

HashMap、Hashtable和ConcurrentHashMap是Java中常见的键值对存储的集合,它们之间的区别如下:

1. 线程安全性:
   - HashMap:非线程安全,不同线程同时操作HashMap可能导致不确定的结果。
   - Hashtable:使用内部锁(synchronized)来保证线程安全,但性能相对较低。
   - ConcurrentHashMap:使用分段锁(Segment)来实现,将整个Map分为多个部分,每个部分独立加锁,允许多个线程同时访问不同部分,提高了并发性能。

2. 键和值的允许性:
   - HashMap和ConcurrentHashMap:键和值都可以为null,允许存储null键和null值。
   - Hashtable:不允许存储null键和null值。

3. 效率与性能:
   - HashMap和ConcurrentHashMap:在单线程环境下,HashMap的性能通常高于ConcurrentHashMap。当存在高并发的多线程环境时,ConcurrentHashMap的并发性能更好。
   - Hashtable:由于使用了内部锁,性能相对较低,不推荐在新的代码中使用。

4. 迭代顺序:
   - HashMap和ConcurrentHashMap:不保证迭代顺序,迭代结果可能是无序的。
   - Hashtable:迭代结果的顺序与存储顺序相同。

总结来说,HashMap是一种非线程安全的集合,性能较好;Hashtable是线程安全的,但性能较差,已不推荐使用;ConcurrentHashMap是线程安全的,且在高并发环境下性能很好,适合多线程并发访问的场景。具体使用哪种集合取决于需求,是否需要线程安全性以及对性能的要求。

四、遍历、迭代集合的方式有哪些?

在Java中,遍历和迭代集合的方式有以下几种:

1. 使用迭代器(Iterator):大多数集合类都实现了Iterator接口,可以使用iterator()方法获取迭代器对象,然后通过`hasNext()`和`next()`方法遍历集合中的元素。

2. 使用增强for循环(foreach):增强for循环是一种简化遍历集合的语法,遍历过程中不需要显式使用迭代器,适用于遍历所有元素且不需要索引的情况。

3. 使用Lambda表达式和Stream API:从Java 8开始,可以使用Lambda表达式和Stream API来遍历集合,可以进行更复杂的操作如过滤、映射等。

4. 使用普通for循环和索引:适用于需要对集合进行索引访问的情况。

public class Traversal {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        //1、使用迭代器进行集合遍历
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            String element=iterator.next();
        }
        //2.使用增强for循环遍历集合
        for (String element : list) {
            //处理元素
        }
        //Java 8提供的新特性
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String element) {
                //处理元素
            }
        });
        //3.使用Lambda表达式和Stream API
        list.stream().forEach(element -> {
            //处理元素
        });
        //4.使用普通的for循环遍历集合,对于有下标要求的场景使用
        for (int i = 0; i < list.size(); i++) {
            String element=list.get(i);
        }
    }
}

对于Map集合的遍历方式常用的有以下三种:

在Java中,可以使用不同的方式来遍历Map集合。以下是几种常用的遍历方式:

1. 使用keySet()方法遍历:通过获取Map的keySet()方法返回的Set集合,然后使用foreach循环遍历Set集合,再通过get()方法获取对应的value值。

Map<String, Integer> map = new HashMap<>();
// 添加元素到map中

for (String key : map.keySet()) {
    Integer value = map.get(key);
    System.out.println("Key: " + key + ", Value: " + value);
}

2. 使用entrySet()方法遍历:通过获取Map的entrySet()方法返回的Set集合,然后使用foreach循环遍历Set集合,每次遍历得到的是一个Map.Entry对象,Map.Entry是Java集合框架中的一个接口,表示Map中的一个键值对,通过该对象的getKey()和getValue()方法获取key和value值。

Map<String, Integer> map = new HashMap<>();
// 添加元素到map中

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    System.out.println("Key: " + key + ", Value: " + value);
}

3. 使用Iterator迭代器遍历:通过获取Map的entrySet()方法返回的Set集合,然后使用Iterator迭代器遍历Set集合,每次迭代得到的是一个Map.Entry对象,通过该对象的getKey()和getValue()方法获取key和value值。

Map<String, Integer> map = new HashMap<>();
// 添加元素到map中

Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String, Integer> entry = iterator.next();
    String key = entry.getKey();
    Integer value = entry.getValue();
    System.out.println("Key: " + key + ", Value: " + value);
}

以上是几种常用的Map集合遍历方式,根据实际情况选择适合的方式进行遍历。

五、Java中集合常用的排序方法有哪些?

Java中集合常用的排序方法有以下几种:

1. 使用Collections.sort()方法:该方法可以对List集合进行排序,使用默认的自然排序方式进行排序,也可以通过传入Comparator对象来实现自定义排序。

2. 使用Arrays.sort()方法:该方法可以对数组进行排序,使用默认的自然排序方式进行排序,也可以通过传入Comparator对象来实现自定义排序。

3. 使用TreeSet集合:TreeSet是有序的集合,它会根据元素的自然顺序进行排序。如果要实现自定义排序,需要在创建TreeSet时传入Comparator对象。

4. 使用Comparable接口:实现Comparable接口的类可以使用Collections.sort()方法或Arrays.sort()方法进行排序。在实现Comparable接口时,需要重写compareTo()方法来定义对象之间的比较规则。

5. 使用Comparator接口:Comparator接口可以用于实现自定义的比较规则。可以通过实现Comparator接口来创建Comparator对象,然后传入Collections.sort()方法或Arrays.sort()方法进行排序。

这些排序方法可以根据具体的需求选择使用,可以根据元素的自然顺序进行排序,也可以根据自定义的比较规则进行排序。

使用最多排序方法的如下面代码所示:

public class ListSort{
    static List<String> list=new ArrayList<>();
    public static void main(String[] args) {
        list.add("aaa");
        list.add("ccc");
        list.add("bbb");
        //1、通过Collection.sort()方法通过传入Comparator对象进行排序
        Collections.sort(list, new Comparator<String>() {
            //compare两个参数的使用
            //如果o1小于o2,返回一个负整数(通常是-1);
            //如果o1等于o2,返回0;
            //如果o1大于o2,返回一个正整数(通常是1)。
            //如果是升序排列就用前一个对象比较后一个对象,反之亦然
            @Override
            public int compare(String o1, String o2) {
                //String的compareTo方法用于比较两个字符串,默认是按照字母的AsCall码表的大小排序
                //升序排列
                return o1.compareTo(o2);
                //降序排列
                //return o2.compareTo(o1);
            }
        });
        list.forEach(System.out::println);

        //2.对于现Comparable接口,重写compareTo方法的类的集合,
        // 可以直接使用Collections.sort()来排序
        List<Person> personList=new ArrayList<>();
        personList.add(new Person("zs",30));
        personList.add(new Person("ls",19));
        personList.add(new Person("wangwu",20));
        Collections.sort(personList);
        personList.forEach(System.out::println);
    }
}
//2.实现Comparable接口,重写compareTo方法来进行自定义排序
class Person implements Comparable<Person>{
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person person) {
        //按照年龄进行降序排序
        return this.age- person.age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Java集合体系是Java重要和用的一部分,主要由四个核心接口:Collection、List、Set和Map组成。 Collection接口是集合体系的父接口,它是最基本的集合接口。它包含了一些用的集合操作方法,如添加、删除、查找、遍历等。它的两个主要子接口是List和Set。 List接口代表了有序的集合,它的实现类有ArrayList、LinkedList和Vector等。List集合可以保留元素的插入顺序,并且允许重复元素存在。 Set接口代表了不允许重复元素的集合,它的实现类有HashSet、TreeSet和LinkedHashSet等。Set集合不保留元素的插入顺序,其主要特点是保证集合没有重复的元素。 Map接口代表了键值对的集合,它的实现类有HashMap、TreeMap和LinkedHashMap等。Map集合的键是唯一的,通过键可以快速查找对应的值。Map集合提供了根据键来存取数据的操作。 除了以上四个核心接口,还有许多与集合相关的类,如Stack、Queue、PriorityQueue等。它们都是集合的扩展和补充。 Java集合体系具有很高的灵活性和扩展性,能够满足各种不同的需求。通过不同的集合类型和方法的运用,我们可以更高效地管理和操作数据。在实际应用,根据具体的业务需求,选择合适的集合类型和方法进行使用,能够提高程序的性能和效率。 总结来说,Java集合体系是非重要的一部分,掌握了集合的基本使用方法和见操作,对于Java程序的开发和设计是非有帮助的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Double丶11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值