一、数组和集合的相互转换
当返回值是数组 / list集合 的时候,我们可以通过中间数据结构 list集合/ 数组去赞数存放数据,最后再调用工具类,转换回去。如数组转换成list ,我们可以通过Arrays.asList( 数组 );
list集合 -> 数组
如果我们要将list集合转换成数组,可以直接调用list.toArray()方法,但这通常需要使用stream流,来进行类型转换,如:
假设方法返回值是int [ ],这里IDEA编译期间就会报错,因为list存放的是Integer ,引用类型,你现在想转换成基本类型int 。
List<Integer> list = new ArrayList<>();int[] a = new int[10];list.toArray(a);
方法1:
我们可以通过stream流:
将list中每个元素转换成int,然后调用toArray方法。
List<Integer> list = new ArrayList<>();
int[] a = list.stream().mapToInt(Integer::intValue).toArray();
注:toArray方法,有无参和有参,无参的话返回Object[ ],有参的话,需要我们指定类型和大小,如
Integer[] array = list.toArray(new Integer[10]);
方法2:
对于ArrayList,我们可以通过for循环+索引
List<Integer> list = new ArrayList<>();int [] res = new int[10];for(int i = 0 ; i < res.length ; i ++){res[i] = list.get(i);}
数组 -> list集合
我们通常是通过Arrays.asList ( )
方法1:
通过Arrays.asList(list集合)
区别:List集合里面不能存放基本类型,所以只能将int[ ]数组当做一个整体,放进list中
int[] res = new int[10];List<int[]> list = Arrays.asList(res); //存放的是int[]Integer[] res1 = new Integer[10];List<Integer> list1 = Arrays.asList(res1);//存放的是Integer
方法2:
Collections工具包下的 addAll方法(集合引用,数组元素(可以是几个值,也可以是一个数组引用))
Integer[] res1 = new Integer[10];List<Integer> list1 = Arrays.asList(res1);Collections.addAll(list1,res1);
方法3:
通过stream流
将array数组转换成流,然后收集到list中
String[] array = {"Element1", "Element2"};
List<String> list = Arrays.stream(array).collect(Collectors.toList());
二、list集合数组的使用场景
首先,如果你需要用到索引,那么直接抛弃LinkedList,在ArrayList和数组中抉择吧。
LinkedList一般用于队列 / 栈,有个前后顺序。【后面会有专门文章讲解】
ArrayList和List中抉择:
如果需要动态扩容(不知道具体大小),使用ArrayList吧,其他场景我认为都可以使用数组,因为无论从空间还是查询效率上,数组会更胜一筹。
注意:
对于ArrayList数据结构,我们也是可以做到,对同一个索引,进行重复覆盖的。
【我第一次接触,以为ArrayList和LinkedList一样,调用add方法,只能一直往后加,后面知道ArrayList有一个add方法,参数是索引 、 value值,方法返回值为void】。
而一个参的add方法(value),方法返回值为boolean。
这个方法对于ArrayList实现,没用,返回值一直是true,
而对于Set数据结构,就有用了,因为set有去重的功能,当有元素重复,则返回false;
ArrayList<Integer> list = new ArrayList<>();list.add(0,1);list.add(0,2);System.out.println(list.get(0)); // 输出2,说明可以对同一索引进行覆盖处理...
LinkedList实现中的add(索引,value)方法
LinkedList<Integer> linkedList = new LinkedList();linkedList.add(0,1);linkedList.add(0,2);System.out.println(linkedList); // 输出[2,1]
三、碰到需要去重的,我们可以考虑用HashSet数据结构。
例1:给你一个整数数组
nums
和一个整数k
。请你从nums
中满足下述条件的全部子数组中找出最大子数组和:
- 子数组的长度是
k
,且- 子数组中的所有元素 各不相同 。
返回满足题面要求的最大子数组和。如果不存在子数组满足这些条件,返回
0
。子数组 是数组中一段连续非空的元素序列。
通过HashSet,保证窗口中的元素不重复,我们不用去加个循环套if逐个判断,窗口是否有重复元素,空间换时间。
public long maximumSubarraySum(int[] nums, int k) {long ans = 0l,sum = 0l; // 数组元素都大于 0 ,不用赋Long.MIN_VALUEHashSet<Integer> window = new HashSet();int left = 0;for(int right = 0; right < nums.length; right++){while(window.contains(nums[right]) || right - left >= k){ //不满足窗口的条件sum -= nums[left];window.remove(nums[left++]);}sum += nums[right];window.add(nums[right]);if(right - left + 1== k) ans = Math.max(ans,sum);}return ans;}
四、判断字符串中是否存在某一特性
判断当前字符串是否存在以元音字母开头或结尾
方法1:通过Hash先去一一存放元音字母,然后通过contains函数
字符串结尾字符,通过word.length( ) -1去获取
private HashSet<Character> vowelSet = new HashSet<>();private void init(){vowelSet.add('a');vowelSet.add('e');vowelSet.add('i');vowelSet.add('o');vowelSet.add('u');}private boolean check(String word){// 判断是否以元音开头或结尾return vowelSet.contains(word.charAt(0)) && vowelSet.contains(word.charAt(word.length()-1));}
五、数组相关
创建一个二维数组
int[][] cnt = new int[][]{{1,2,3},{4,5,6},{7,8,9}};int[][] cnt1 = new int[3][3];cnt1[0][0] = 1;cnt1[0][1] = 2;//以下是错误写法int[][] cnt = new int[3][3]{{1,2,3},{4,5,6},{7,8,9}};
六、排序
TreeSet中覆盖Comparator接口,重写compare方法 ,o1 - o2 表示升序,o2 - o1 表示降序
对于List<List<Node>>结构,有个场景:
将多个List<Node>中的Node元素,根据value属性进行排序,并放在一个数组当中
先全部放进来,然后直接调用sort方法【sort方法也能直接对二维数组进行排序,默认是一维的】
int n = nums.size();int sumLen = 0;for(List<Integer> list : nums){sumLen += list.size();}int[][] temp = new int[sumLen][2];//将多个列表 合并成一个结构int k = 0;for(int i = 0 ; i < n ; i ++){for(int x : nums.get(i)){temp[k][0] = x; // 存具体的值temp[k++][1] = i; // 存索引}}Arrays.sort(temp,(a,b) -> a[0] - b[0]);