集合

文章目录

    • Java集合容器面试题(2020最新版)
    • 集合为什么不能存放基本数据类型
    • 数组和集合的比较
    • 集合容器
    • List常用方法
    • Set使用方式
    • Map常用方法
    • 集合排序
    • 集合新特性
    • 集合脑图

Java集合容器面试题(2020最新版)

Java集合容器面试题(2020最新版)

集合为什么不能存放基本数据类型

  • Java集合不能存放基本数据类型,只能存放对象的引用。每个集合元素都是一个引用变量,实际内容都存放在堆内或方法区里面,但是基本数据类型是在栈内存上分配空间的,栈上的数据随时会被收回。

数组和集合的比较

  • 数组不是面向对象的,存在明显的缺陷,集合弥补了数组的缺点,比数组更灵活更实用,而且不同的集合框架类可适用不同场合。如下:
    • 数组能存放基本数据类型和对象,而集合类存放的都是对象,集合类不能存放基本数据类型。数组和集合存放的对象皆为对象的引用地址。
    • 数组容易固定无法动态改变,集合类容量动态改变。
    • 集合有多种实现方式和不同适用场合,不像数组仅采用顺序表方式。
    • 集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性即可实现各种复杂操作,大大提高了软件的开发效率。
      集合_第1张图片

集合容器

  • Collection和Map,是集合容器的根接口。
    • Collection的子接口:
      • Set:接口—实现类: HashSet、LinkedHashSet
        • Set的子接口SortedSet接口—实现类:TreeSet
      • List:接口—实现类: LinkedList,Vector,ArrayList

List常用方法

  • 增:add、addAll
  • 删:remove
  • 改:set
  • 查:get、subList、listIterator(可执行遍历过程中的增删改查)
  • 遍历:普通for、增强for、forEach、iterator(collection接口方法,遍历及移除)
public class showMessage {
    public static void main(String[] args) {
        PG pg1 = new PG(01, 24, "张三", 10000.0, 85);
        Employee pg2 = new PG(02, 26, "李四", 12000.0, 95);
        Employee pm1 = new PM(1001, 45, "tom", 70000.0, 90);
        Employee pm2 = new PM(1002, 37, "jim", 65000.0, 87);

        List<? super Employee> list = new ArrayList<>();
        list.add(pg1);
        list.add(pg2);
        list.add(pm1);
        list.add(pm2);

        // 普通for
        for (int i = 0; i < list.size(); i++) {
            Employee employee = (Employee)list.get(i);
            employee.show();
        }

        // lamda
        list.forEach(emp -> {
            Employee emp1 = (Employee) emp;
            emp1.show();
        });

        //迭代器
        ListIterator<? super Employee> listIterator = list.listIterator();
        while (listIterator.hasNext()) {
            Employee employee = (Employee)listIterator.next();
            employee.show();
        }

        // 增强for
        for (Object o : list) {
            Employee o1 = (Employee) o;
            o1.show();
        }

    }
}

Set使用方式

  • 如果存放自定义的引用对象,需重写hashCode和equals方法。
  • HashSet、LinkedHashSet元素可以为null值,TreeSet不可以。

Map常用方法

  • 增:put
  • 删:remove、clear
  • 判断:isEmpty、containsValue、containsKey
  • 查:get
  • 遍历:keySet、entrySet
public class ShowMessage {
    public static void main(String[] args) {
        Map<Integer,Employee> map = new HashMap<>(4);
        PG pg1 = new PG(01, 24, "张三", 10000.0, 85);
        Employee pg2 = new PG(02, 26, "李四", 12000.0, 95);
        Employee pm1 = new PM(1001, 45, "tom", 70000.0, 90);
        Employee pm2 = new PM(1002, 37, "jim", 65000.0, 87);
        map.put(pg1.getId(), pg1);
        map.put(pg2.getId(), pg2);
        map.put(pm1.getId(), pm1);
        map.put(pm2.getId(), pm2);

        //entrySet
        for (Map.Entry<Integer, Employee> key : map.entrySet()) {
            key.getValue().show();
        }

        //keySet
        for (Integer key : map.keySet()) {
            map.get(key).show();
        }
    }
}

集合排序

  • Collections.sort(List list):自然排序,参与排序的对象需实现comparable接口,重写其compareTo()方法,内部比较器。
public class User  implements  Comparable<User>{
    private Integer id;
    private String name;
    private Integer age;

    /**
     * 自定排序的规则
     *   1.根据用户年龄 升序排列
     *    2.年龄一致的时候  利用id进行升序排列
     * @param user
     * @return
     */
    @Override
    public int compareTo(User user) {
        Objects.requireNonNull(user);
        if(this==user){
            return 0;
        }
        int result = this.age.compareTo(user.age);
        if(result==0){
           result =  this.id.compareTo(user.id);
        }
        return  result;//int;
    }
}
  • Collections.sort(List list,Comparator c):定制排序,或自定义排序,需编写匿名内部类,先new一个Comparator接口(java.util包)的比较器对象c,同时实现compare()其方法;,外部比较器。
    Collections.sort(userList,(user1,user2)->{
        int result = user2.getAge().compareTo(user1.getAge());
        if(result == 0){
            result = user2.getId().compareTo(user1.getId());
        }
        return result;
    });
  • 第一种方法不够灵活,实体类实现了comparable接口(java.lang包)后,会增加耦合,如果在项目中不同的位置需要根据不同的属性调用排序方法时,需要反复修改比较规则(按name还是按age),二者只能选择其一,会起冲突。第二种就很好地解决了这个问题,在需要的地方,创建个内部类的实例,重写其比较方法即可。

集合新特性

    private static void demo2() {
        //去除重复数据
        List<Integer> num = new ArrayList<>();
        Collections.addAll(num, 1, 10, 1, 2, 3, 3, 2);

        // 去重
        List<Integer> collect = num.stream().distinct().collect(Collectors.toList());

    }

    private static void demo1() {
        //删除名字里面包含m的元素
        List<User> userList = new ArrayList<>(10);
        Collections.addAll(userList,
                new User(1, "jim", 20),
                new User(3, "tom", 18),
                new User(2, "lily", 18),
                new User(5, "zhangsan", 18),
                new User(5, "zhm", 18),
                new User(4, "kim", 18));
        //第一种方式
        userList.removeIf((user -> user.getName().contains("m")));
        
        //第二种方式:获得并行化流
        Stream<User> userStream = userList.parallelStream();// list集合的所有的元素都在userStream里面
        userStream = userStream.filter(user -> !user.getName().contains("m"));//userStream只有不包含m的对象
        List<User> collect = userStream.collect(Collectors.toList());

        //简写(推荐)
        List<User> collect = userList.parallelStream().filter(user -> !user.getName().contains("m")).collect(Collectors.toList());
    }

集合脑图

集合_第2张图片

你可能感兴趣的:(集合)