一、java常用的数据结构的特点和应用场景
1.数组
可以容纳一串数字,每个数字有单独的索引,可以方便的通过索引查找相应位置的数值是多少。
2.字符串String
一串字母,不支持用[ ]直接访问其中的字符,不能直接修改,需要用toCharArray转化成char[]才可以修改。
字符串可以直接用+拼接,但效率低,for循环中尽量用StringBuilder进行字符串的拼接。
字符串的比较用equal别用==,等号容易出现bug。
3.动态数组ArrayList
ArrayList是一个动态可修改的数组,没有固定大小限制,我们可以添加或删除元素。对数组的包装,与C++中的Vector容器功能类似。
4.双链表LinkedList
链表不会按照线性顺序存储数据,它在每一个节点里存下一个节点的地址。单链表包含两个值,当前节点的值和下一个节点的链接。
我们可以用双链表对头部和尾部的元素操作,直接操作头部的效率更高,其中contains方法的时间复杂度是O(N)因为它需要遍历整个链表。
ArrayList和LinkList都是List的子类,二者返回的结果均满足题目要求的List类型。
频繁的访问列表中某一个元素,或只需要在列表末尾添加和元素时用ArrayList。
通过循环迭代访问列表中某些元素,或频繁的在列表开头、中间、末尾等位置添加删除元素时用LinkedList。
5.哈希表HashMap
HashMap是一个散列表,存储的是键值对映射(key-value)
HashCode最多允许一条记录的键值为null,HashMap无序,不会记录插入的顺序。
6.哈希集合HashSet
不允许有重复元素的集合,允许有null值。
7.队列Queue
实现了先进先出的数据结构
8.堆栈Stack
栈(Stack)实现了一个后进先出(LIFO)的数据结构。
声明时
int对应Integer
char对应Character
二、java常用数据结构的详细使用方法。
1.数组
①初始化方法
int m=5,n=10; //初始化一个大小为10的int数组,其中默认值初始化为0 int[] nums=new int[n]; //初始化一个m*n的二维布尔数组,其中的元素默认初始化为false bollean[][] visited=new boolean[m][m];
②做题时如果题目以函数参数的形式传入,先做个非空检查,然后用索引下标访问其中的元素。
if(nums.length==0){ return; } for(int i=0;i<nums.length;i++){ //访问nums[i] }
2.字符串String
①String 的常见特性
String s1 = "Hello world!"; //获取s1[2]中的字符 char c = s1.charAt(2); char[] chars = s1.toCharArray(); chars[1] = 'a'; String s2 = new String(chars); // 输出:Hello World! System.out.println(s2); // 一定要用equals方法判断字符串是否相同 if (s1.equals(s2)) { System.out.println("s1-s2相同"); } else { System.out.println("不相同"); } // 少量的字符串拼接可以直接使用加号 String s3 = s1 + "newString"; System.out.println(s3);
// 遍历字符串中的每个字符
for(Character c:s.toCharArray()){}
②更高效的字符串拼接方式StringBuilder
StringBuilder sb = new StringBuilder(); for (char c = 'a'; c <= 'f'; c++) { sb.append(c); } // append方法支持字符、字符串、数字等类型 sb.append('g').append("hij").append(123); String res = sb.toString(); System.out.println(res);
3.动态数组ArrayList
①初始化ArrayList
// 初始化一个存储String的动态数组 ArrayList<String> Strings = new ArrayList<>(); // 初始化一个存储int的动态数组 ArrayList<Integer> nums = new ArrayList<>();
② 常用方法,用E表示元素类型
// 在数组尾部添加元素e bolean add(E e); nums.add(68); // 判断数组是否为空 boolean isEmpty() System.out.println(nums.isEmpty()); // 返回数组中元素个数 int size(); System.out.println(nums.size()); // 返回索引index的元素 E get(int index); System.out.println(nums.get(0));
//返回某个元素的index int indexOf(ArrayList list)
System.out.println(list.indexOf(34))
4.3双链表LinkedList
①初始化一个双链表
// 初始化一个存储int类型数据的双链表
LinkedList<Integer> nums = new LinkedList<>()
// 初始化一个存储String类型数据的双链表;
LinkedList<String> =new LinkedList<>();
②双链表常用的方法
// 在链表尾部添加元素e void add(E e) nums.add(18); // 在链表头部添加元素e void addFirst(E e) strings.addFirst("fitstChar"); // 判空 boolean isEmpty() System.out.println(strings.isEmpty()); // 返回链表中元素个数 int size() System.out.println(nums.size()); // 删除链表头部第一个元素 removeFirst() strings.removeFirst(); // 删除链表尾部最后一个元素 removeLast() nums.removeLast(); // 判断链表中是否存在元素o boolean contains(object o) System.out.println(nums.contains(18)); System.out.println(nums.contains("fitstChar"));
5.哈希表HashMap
①HashMap的初始化方法
// 整数映射到字符串的哈希表 HashMap<Integer, String> stringMap = new HashMap<>(); // 字符串映射到数组或整数的哈希表 HashMap<String, Integer> intMap = new HashMap<>();
②常用的方法
//K表示键的类型,V代表值的类型 // 将key和value键值对存入哈希表 V put(K key,V value) 如果哈希表中有当前key,则修改相应的value stringMap.put(28301, "star"); intMap.put("star", 28301); // 判断哈希表中是否存在键key boolean containsKey(Object key) System.out.println(intMap.containsKey("star")); System.out.println(stringMap.containsKey(28301)); // 获得键key对应的值,若key不存在,返回null V get(Object key) System.out.println(intMap.get("star")); System.out.println(stringMap.get(28301)); // 如果key不存在,将键值对key和value存入哈希表,如果存在啥也不做 V putIfAbsent(K key,V value) stringMap.putIfAbsent(110, "feijing"); intMap.putIfAbsent("huojing", 119); // 获得key的值,如果key不存在,返回与Value类型相同的defaultValue V getOrDefault(Object key,V defaultValue) System.out.println(stringMap.getOrDefault(110, "没有")); System.out.println(intMap.getOrDefault("huoji", 1199)); // 获得哈希表中所有key Set<k> keySet() System.out.println(stringMap.keySet()); System.out.println(intMap.keySet()); // 如果key存在,删除key并返回对应的值 V remove(Object key) System.out.println(stringMap.remove(110)); System.out.println(intMap.remove("huojing"));
6.哈希集合HashSet
①HashSet初始化方法:
//初始化一个存储int类型数据的哈希集合 Set<Integer> set = new HashSet<>();
②哈希集合常见的方法:
//如果e不存在,则将e添加到哈希表集合 boolean add(E e);
set.add(168);
////判断元素o是否存在于哈希集合中 boolean contains(Object o);
System.out.println(set.contains(168));
////如果元素o存在,则删除元素o boolean remove(Object o);
set.remove(168);
7.队列Queue
①初始化一个队列,Queue是一个接口(Interface)
//新建一个存储String的队列 Queue<String> q = new LinkedList<>();
②常用方法
//常用的一些方法,用E表示元素的类型
//判断队列是否为空 boolean isEmpty()
//返回队列中元素的个数 int size(),返回的结果不能转化为字符串,直接拼接即可
//返回队头的元素 E peek()
//删除并返回队头元素 E poll()
//将元素e插入队尾 boolean offer(E e)
q.offer("hello");
q.offer("world!");
//返回队头的元素 E peek()
//删除并返回队头元素 E poll()
//将元素e插入队尾 boolean offer(E e)
if (!q.isEmpty()) {
System.out.println(q.size());
// System.out.println( q.size().toString()); 转换类型会报错:java无法取消引用int
System.out.println("队头的元素为:" + q.peek().toString());
System.out.println("删掉队头的元素:" + q.poll().toString());
8.堆栈Stack
①初始化
//初始化一个堆栈 Stack<String> s = new Stack<>();
②常用方法
//常用的方法 //判断堆栈是否为空 boolean isEmpty() //返回堆栈中元素的个数 int size() //将元素压入栈顶 E push(E item) //返回栈顶元素 E peek() //删除并返回栈顶元素 E pop() s.push("hello"); s.push("world"); if (!s.isEmpty()) { System.out.println("堆栈内元素个数为:" + s.size()); System.out.println("栈顶的元素为:"s.peek().toString()); System.out.println("删除栈顶的元素为:"s.pop().toString());