Java十分钟精通集合的使用与原理下篇

List集合:

ArrayList:

底层是数组结构,储存有序并且可以重复的对象

package SetTest;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ArrayListTest {
    public static void main(String[] args) {

		//创建ArrayList的对象
        List<Integer> list = new ArrayList<>();
        //使用add方法就可以添加
        list.add(1);
        list.add(2); //是可以重复的
        list.add(2);
        list.add(3);
        list.add(4);

        //使用集合工具类Collections
        Collections.sort(list); //排序
        Collections.reverse(list); //反转
        System.out.println(list.toString());

    }
}

输出:

[1, 2, 2, 3, 4]
[4, 3, 2, 2, 1]
//在ArrayList中重复数据是没问题的

LinkedList:

双向链表式存储,存储有序可重复的对象。LinkedList的实现机制与ArrayList的不同,ArrayList底层是数组实现的,每次插入值的时候先扩容数 组的长度,通过下标获取到该数组的值因此查询元素的效率很高,但是插入和删除需要位移效率很低,所以经 常对元素插入或者删除操作建议不要使用ArrayList,而要采用LinkedList。LinkedList采用双向链表 式存储在增加和删除元素的时候不需要位移,插入和删除效率高。

LinkedList的储存结构:

总结:查询多的时候用ArrayList,删除和插入多就用LinkedList

List<Integer> list = new LinkedList<>();//创建LinkedList的对象

其他操作与ArrayList一致

Vector:

Vector和ArrayList集合没有什么太大的区别,底层都是数组实现的,作用也是一致,用来存储大量的有序 的可重复的对象,一般用于大量数据的查询。唯一的区别在于Vector是线程安全的,ArrayList是非线程安全的。

 List<Integer> list = new Vector<>();//创建Vector的对象

其他操作与ArrayList一致

Set集合:

HashSet:

是以Hash算法来记录再内存中无序存储的对象

HashSet源码:

public HashSet() {
	map = new HashMap<>();
}

说明HashSet底层是依赖于HashMap以键值对的形式来存储的无序的集合,通过键来找到值,但是键是 以hash算法来存储的无序集合。

TreeSet:

TreetSet是SortSet接口的实现类,TreeSet可以保证元素处于排序状态再保存。它采用的是红黑树算法数 据结构来存储集合元素。TreeSet支持两种排序:自然排序和定制排序,默认采用自然排序

自然排序:

package SetTest;

import java.util.Set;
import java.util.TreeSet;

public class TreeSetTest {
    public static void main(String[] args) {

        //treeSet是以红黑树算法将值先排序再保存
        Set<Integer> tre = new TreeSet<>();
        tre.add(5);
        tre.add(3);
        tre.add(8);
        tre.add(1);
        tre.add(4);
        for (Integer val:tre){
            System.out.println(val);
        }
    }
}

输出:

1
3
4
5
8

定制排序:

Student类:

package TreeSet;

public class Student implements Comparable<Student> {

    private String name;
    private int age;
    private char sex;

    public Student(String name, int age, char sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    @Override
    public String toString(){
        return "学生的信息是{"+name+age+sex+"}";
    }

    @Override
    public int compareTo(Student obj) {
        //这里使用年龄来比较排序
        int num = this.age-obj.age;
        return num;
    }
}

测试类:

package TreeSet;

import java.util.Set;
import java.util.TreeSet;

public class test {
    public static void main(String[] args) {

		//这里生成对象的年龄不按照大小来生成
        Student stu1 = new Student("张三",40,'男');
        Student stu2 = new Student("李四",32,'男');
        Student stu3 = new Student("王五",25,'男');

        Set<Student> treeSet = new TreeSet<>();
        treeSet.add(stu1);
        treeSet.add(stu2);
        treeSet.add(stu3);

        for (Student stu:treeSet
             ) {
            System.out.println(stu.toString());

        }
    }
}

输出结果:

结果就是按照年龄的大小来进行排序:(这个就是TreeSet的定制排序)

学生的信息是{王五25男}
学生的信息是{李四32男}
学生的信息是{张三40男}

LinkedHashSet:

内部是一个双向链表式结构,所以它插入的值式有序的。因为它插入的时候是使用链表式维护插入的顺 序,所以获取元素的时候应该和插入的顺序一致。但是LinedHashSet性能上低于HashSet,因为除了维护值 以外还需要维护他们的顺序:

package SetTest;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSetTest {
    public static void main(String[] args) {

        //LinkedHashSet 按照插入的顺序读取值
        Set<Integer> set = new LinkedHashSet<>();
        set.add(40);
        set.add(20);
        set.add(10);
        set.add(30);

        for (Integer val:set){
            System.out.println(val);
        }
    }
}

输出:(会按照输入的顺序去读值)

40
20
10
30

Map集合:

HashMap:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapTest {
    public static void main(String[] args) {

        Map<String,String> map = new HashMap<>();
        map.put("red","红色");
        map.put("yellow","黄色");
        map.put("green","绿色");

        System.out.println(map);

        System.out.println(map.get("yellow"));//通过get键去获取值

	}
}

输出:

{red=红色, green=绿色, yellow=黄色}
黄色 // System.out.println(map.get("yellow"));

HashMap的两种遍历方法:

通过for遍历所有的键,根据键来获取到值(接上部分代码即可)

   for (String stu:map.values()
             )
            System.out.println(stu.toString());{
        }

输出:

红色
绿色
黄色

用迭代器的方式:(接上部分代码即可)

        Set<String> keys = map.keySet();
        Iterator<String> it = keys.iterator();
        while(it.hasNext()){
            String key = it.next();
            String stu = map.get(key);
            System.out.println(stu.toString());
}

输出:

红色
绿色
黄色

注意:如果是存储大量的数据,我们一般是不会用Map去存储。Map一般用于存储小量并且可以无序的 键值对存储的数据。比如登录页面的用户名、密码等等。

LinkedHashMap:

LinkedHashMap是以链表式存储的HashMap,并且是以Hash算法来获取hashcode的值来获取内存中的数 据,存储的顺序和读取的顺序一致:

import java.util.LinkedHashMap;
import java.util.Map;
public class LinkHashMap {

    public static void main(String[] args) {

		//在HashMap里面,添加使用put方法!!
        Map<String,String> map = new LinkedHashMap<>();
        map.put("yellow","黄色");
        map.put("green","绿色");
        map.put("red","红色");
        System.out.println(map);
    }
}

输出:

{yellow=黄色, green=绿色, red=红色}

HashTable:

Map<String,String> map = new Hashtable<>();

HashMap和HashTable的作用一样,都是无序的键值对形式存储,HashTable考虑线程安全,HashMap不考 虑线程安全,其他操作一致。

ConcurrentHashMap: 也是和HashMap线程一样,但是它考虑线程安全。HashTable是采用给当前线程加锁实现线程安全, ConcurrentHashMap是采用分段锁机制来实现线程安全:

Map<String,String> map = new ConcurrentHashMap<>();

EnumMap: 专门用来存储枚举的Map集合:

package SetTest;
import java.util.Map;
public class EnumMap {

    //枚举
    public enum color{
        RED,GREEN,YELLOW
    }
    public static void main(String[] args) {

        //枚举map
        Map<color,String> map = new java.util.EnumMap<color, String>(color.class);
        map.put(color.RED,"红灯");
        map.put(color.GREEN,"绿灯");
        map.put(color.YELLOW,"黄灯");
        System.out.println(color.RED);
        String info = map.get(color.RED);
        System.out.println("信号信息是:"+info);

    }
}

集合和数组之间的转换:

import com.sun.corba.se.spi.ior.ObjectKey;
import java.util.Arrays;
import java.util.List;

/**
 * 集合和数组之间的转换
 */

public class SetToArr {
    public static void main(String[] args) {
        String name [] =  new String[]{"张三","李四","王五","赵六"};

        //将各种数据转换成list集合
        List<String> list1 = Arrays.asList(name);
        List<String> list2 = Arrays.asList("aa","bb","cc");
        List<Integer> list3 = Arrays.asList(100,200,300);
        System.out.println("list集合:"+list2);

        //list转数组
        Object [] newArr = list2.toArray();
        String newStr = list2.toString();
        System.out.println("数组:"+newStr);

    }
}

输出:

list集合:[aa, bb, cc]
数组:[aa, bb, cc]

这些就是常用的集合代码举例,大家可以结合上一章的理论知识来看,在这里写的都是一些很简洁的例子,大家多看看就可以理解。

到此这篇关于Java十分钟精通集合的使用与原理下篇的文章就介绍到这了,更多相关Java 集合内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java集合框架之List ArrayList LinkedList使用详解刨析

    目录 1. List 1.1 List 的常见方法 1.2 代码示例 2. ArrayList 2.1 介绍 2.2 ArrayList 的构造方法 2.3 ArrayList 底层数组的大小 3. LinkedList 3.1 介绍 3.2 LinkedList 的构造方法 4. 练习题 5. 扑克牌小游戏 1. List 1.1 List 的常见方法 方法 描述 boolean add(E e) 尾插 e void add(int index, E element) 将 e 插入到 inde

  • Java使用list集合remove需要注意的事项(使用示例)

    目录 错误使用示例一: 解决方案一: 解决方案二: 错误使用示例二: 分析结果原因: 解决方案: 在实际开发中有时候会碰到这样的场景,需要将一个list集合中的某些特定的元素给删除掉,这个时候用可以用List提供的remove方法来实现需求. List中的remove方法传入的参数可以是集合的下标,也可以是集合中一个元素,也可以是一个集合. 错误使用示例一: 这里我使用的是增强for循环,会发现直接报错. List集合的一个特点是它其中的元素时有序的,也就是说元素的下标是根据插入的顺序来的,在删

  • Java集合框架之Stack Queue Deque使用详解刨析

    目录 1. Stack 1.1 介绍 1.2 常见方法 2. Queue 2.1 介绍 2.2 常见方法 3. Deque 3.1 介绍 3.2 常见方法 1. Stack 1.1 介绍 Stack 栈是 Vector 的一个子类,它实现了一个标准的后进先出的栈.它的底层是一个数组. 堆栈只定义了默认构造函数,用来创建一个空栈.堆栈除了包括由 Vector 定义的所有方法,也定义了自己的一些方法. 1.2 常见方法 方法 描述 E push(E item) 压栈 E pop() 出栈 E pee

  • Java十分钟精通集合的使用与原理上篇

    目录 什么是集合? 集合分为Collection和Map两种体系 一.Collection接口: 二.Map接口下分为HashMap和TreeMap: 集合总结: Collections工具类: 什么是集合? 比如我们去买超市买很多东西,我们不可能拿一样就去收银台,我们可能是先放到购物车内,然后再统一处理,所以购物车相当于一个容器,可以装很多东西,在Java中的集合也是相当于一个容器,可以装很多数据. 集合继承关系图: 但是这张图太复杂了,我们看一张简便的: 集合分为Collection和Map

  • java使用CollectionUtils工具类判断集合是否为空方式

    目录 使用CollectionUtils工具类判断集合是否为空 判断集合为空(List为null或size()==0) 判断集合不为空(List不为null且size()!=0) 判断集合是否为空底层 集合判断是否为空工具类(CollectionUtils) 工具类 方法 使用CollectionUtils工具类判断集合是否为空 判断集合为空(List为null或size()==0) 1.CollectionUtils.isEmpty(null): true 2.例:List<String>

  • Java十分钟精通集合的使用与原理下篇

    List集合: ArrayList: 底层是数组结构,储存有序并且可以重复的对象 package SetTest; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ArrayListTest { public static void main(String[] args) { //创建ArrayList的对象 List<Integer> list = ne

  • Java十分钟精通接口的使用与原理

    何为接口? 官方解释: Java内的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 个人理解解释: 其实接口可以理解为一种特殊的类,这个类里面全部是由全局常量和**公共的抽象方法(需要重写)所组成.接口是解决Java无法使用多继承的一种手段.我们可以把接口理解为是一个100%的抽象类,既接口中的方法必须全部是抽象方法.反正接口里面都是方法,但是没有方法体,其他类实现这个接口后重

  • Java十分钟精通泛型的使用与原理

    什么是泛型? 简而言之:<>泛型就是用来约束类.方法.属性上的数据类型,比如 List<Integer> list = new ArrayList<Integer>(); new ArrayList这个集合的元素只能添加Integer类型. 为什么需要泛型? Java推出泛型之前,程序员可以构建一个Object类型的集合,该集合能够存储任何的数据类型,而在使用该 集合的时候,需要程序员明确知道每个元素的具体的类型并向下转型,否则容易引发ClassCastExceptio

  • Java十分钟精通包装类的使用与操作

    包装类 何为包装类? 基本类型包装类的概述: 将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据 包装类是将基本数据类型的值包装为Java中的对象,Java语言为8种基本数据类型分别提供了包装类 首先看一下八大数据类型的包装类: 包装类型出现的原因: 因为Java是一个面向对象的语言,基本类型并不具有对象的性质,为了与其他对象"接轨"就出现了包装类型,它相当于将基本类型"包装起来",使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本

  • Java十分钟精通Lambda表达式

    目录 1.简介 2.Lambda表达式的使用: 1.在普通方法内的使用 2.带参方法的使用 3.Lambda表达式实现多线程 4.Lambda表达式操作运算 5.Lambda表达式方法引用 6.Lambda表达式对集合的使用 3.总结 1.简介 首先Lambda表达式是属于Java8的 一个新特性,提供Java编程中对于函数式编程的支持,有助于代码的简洁,可以取代大半部分的匿名函数,尤其对于集合的遍历和集合的操作,极大的简化了代码. Lambda表达式的主体: 函数式接口: 注意: Lambda

  • Java十分钟精通反射机制原理

    什么是反射? 反射机制是在运行状态中,它为Java提供一种"操作对象"的能力,在运行状态下,通过Class文件对象,可以调用到任何类里面的属性.方法.以及构造方法,包括私有的,所有的类在反射机制面前都是透明的 自己的概括:通过Class文件对象可以看到这个类里面的所有东西,并且可以使用和修改 反射的前提是获取Class文件对象((字节码对象),那么一共有三种方式获取: Class.forName("全类名") ----通过Class类的静态方法(最常用) 类名.cl

  • Java十分钟精通Log4j日志的使用

    目录 为什么要用日志? 下载: 详细步骤: 一.打开IDEA 二.创建日志对象 为什么要用日志? 我们知道,程序在运行过程中会产生很多很多信息,比如在几点几分的时候运行了,运行的结果是怎么样的?为了我们更加了解程序运行的情况,可以通过日志来查看,日志可以在控制台输出,也可以输出至指定的文件内,在下面的文章中具体的给大家介绍. 下载: Log4J是Apache公司的开源项目,用于日志处理.下载地址: https://logging.apache.org/log4j/2.x/download.htm

  • Java十分钟精通异常处理机制

    目录 异常处理机制的底层原理 异常的继承关系图 异常的处理 一.try-catch-finally结构 二.多catch处理不同的异常: 三.throws声明异常/throw抛出异常: 四.自定义异常: 五.常见的异常 异常处理机制的底层原理 抛出异常,在执行一个方法时,如果发送了异常,则这个方法生成代表该异常的一个对象,停止当前执行的 路径,并把异常提交给jre. 捕获异常:jre得到该异常后,虚招相应的代码来处理该异常.jre在方法的调用栈中查找,从生成异常的 方法开始回溯,直到找到相应的异

  • Java十分钟精通内部类的使用

    内部类: 其实内部类顾名思义,就是类中类,一个类里面还有一个类. 内部类分为四种: 普通内部类 静态内部类 方法内部类 匿名内部类 我们一一去了解一下~~ A.普通内部类: 我们先通过代码去了解一下: package InternalClass; /** * 内部类 */ public class Car { public int a = 10; public int b = 20; //外部类的方法 public void method() { System.out.println("我是外部

随机推荐