黑马程序员——Java之集合框架工具类Collections、Arrays以及Java新特性
2015-12-28 15:32
816 查看
内容提要:
Collections
Arrays
Java新特性
算法部分分析
Collections
Collections是对集合框架的一个工具类,其包含的方法都是静态的,不需要创建对象,并未封装特有数据。
在Collections工具类中大部分方法是用于对List集合进行的操作,如比较、二分查找、排序等等。
常见操作:
查找、替换、排序、反转、同步集合等等。
代码分析:练习使用Collections工具类,以及常用方法。
Collections与Collection的区别:
Collection是集合框架中的一个顶层接口,他里面定义了单列集合的共性方法。
Arrays
Arrays是用于操作数组的工具类,他里面的方法也全部是静态的,不需要创建对象。
把数组变成List集合的好处:可以使用集合的思想和方法来操作数组中的元素。
集合变数组
使用Collection接口中的toArray方法。
高级for循环:
格式:
for(数据类型 变量:被遍历的集合或数组 ){执行语句}
说明:
其一、对集合进行遍历,只能获取集合元素,但是不能对集合进行操作,可以看做是迭代器的简写形式;
其二、迭代器除了遍历,还可以进行remove集合中的元素动作,如果使用ListIterator,还可以在遍历过程中对集合进行增删改查。
普通for循环和高级for循环的区别:
高级for循环有一个局限性,必须有被遍历的目标(集合或数组);
普通for循环遍历数组时有索引。建议在遍历数组的时候,还是希望使用传统for循环,因为可以定义脚标
如果一个方法在参数列表中传入多个参数,但个数不确定时,就可以使用可变参数。
可变参数,其实就是数组参数的简写,不用每一次都手动地建立数组对象,只要将要操作的元素作为参数传递即可,隐式将这些参数封装成了数组。
没加static导入的是类,加上static导入的全是某一个类中的静态成员,这样在调用该类的静态方法时可以不用再写类名。
需要注意的是:当导入的两个类中有同名成员时,需要在成员前加上相应的类名;当类名重名时,需要制定具体的包名。
排序算法:选择排序、冒泡排序等等
查找:二分查找等等
进制转换:
Collections
Arrays
Java新特性
算法部分分析
Collections
Collections是对集合框架的一个工具类,其包含的方法都是静态的,不需要创建对象,并未封装特有数据。
在Collections工具类中大部分方法是用于对List集合进行的操作,如比较、二分查找、排序等等。
常见操作:
查找、替换、排序、反转、同步集合等等。
import java.util.*; /* * 集合框架的工具类: * Collections:*/ public class CollectionsDemo { public static void sop(Object obj) { System.out.println(obj); } public static void main(String[] args) { // 定义了一个List集合,存放String类型的元素 List<String> list = new ArrayList<String>(); list.add("zd"); //list.add("ay"); list.add("asc"); list.add("az"); list.add("a"); list.add("az"); sop(list); //打印原集合元素 // 使用Collections方法对List按照默认方式排序,调用String中的compareTo()方法 Collections.sort(list); sop(list); // 以默认方式排序后,输出最后的元素 String max1 = Collections.max(list); sop("max1 = " + max1); // 此外,还可以按照自定义方式排序 Collections.sort(list, new StrLenComparator()); sop(list); // 以自定义方式排序后,输出最后的元素 String max2 = Collections.max(list, new StrLenComparator()); sop("max2 = " + max2); //binarySearch()方法使用默认排序方式,前提是集合必须是有序的 int index1 = Collections.binarySearch(list, "ay"); //binarySearch()方法还可以使用自定义排序方式 //int index1 = Collections.binarySearch(list, "ay", new StrLenComparator()); int index2 = halfSearch(list, "ay"); // 自定义函数 //默认排序结果:[a,asc,az,az,zd];输出结果是-(2)-1 System.out.println("index1 = " + index1 + "; index2 = " + index2); } public static int halfSearch(List<String> list, String key) { int min, mid, max; max = list.size() - 1; min = 0; while (min <= max) { mid = (min + max) >> 1; String str = list.get(mid); int num = str.compareTo(key); if (num > 0) max = mid - 1; else if (num < 0) min = mid + 1; else return mid; } return -min - 1; } } class StrLenComparator implements Comparator<String> { public int compare(String s1, String s2) { if (s1.length() > s2.length()) return 1; if (s1.length() < s2.length()) return -1; return s1.compareTo(s2); } }
代码分析:练习使用Collections工具类,以及常用方法。
/* * 程序练习使用Collections上的方法 * */ import java.util.*; public class CollectionsDemo2 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("zd"); list.add("asc"); list.add("az"); list.add("a"); list.add("az"); sop(list); //将集合的全部元素替换成指定内容:"az" //Collections.fill(list, "az"); sop(list); // 将集合的部分元素替换成指定内容:"az"-->"pp" //Collections.replaceAll(list, "az", "pp"); sop(list); //将集合元素反转 Collections.reverse(list); sop(list); } public static void sop(Object obj) { System.out.println(obj); } }
Collections与Collection的区别:
Collection是集合框架中的一个顶层接口,他里面定义了单列集合的共性方法。
import java.util.*; public class CollectionsDemo3 { public static void main(String[] args) { reverseOrderDemo(); shuffleDemo(); } public static void sop(Object obj) { System.out.println(obj); } public static void reverseOrderDemo() { //默认顺序 //TreeSet<String> ts = new TreeSet<String>(); //[a, asc, az, zd] //默认顺序的反转 //TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder()); //[zd, az, asc, a] //指定顺序的反转 TreeSet<String> ts = new TreeSet<String>(new SLComparator()); //[a, az, zd, asc] //TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new SLComparator())); //[asc, zd, az, a] //相当于是指定了排序的顺序,比如可以指定按照长度排序 //此外,还可以对自定义的比较器进行强行逆转,在其后增加参数即可 ts.add("zd"); ts.add("asc"); ts.add("az"); ts.add("a"); ts.add("az"); sop(ts); } public static void shuffleDemo() { List<String> list = new ArrayList<String>(); list.add("zd"); list.add("asc"); list.add("az"); list.add("a"); list.add("az"); //随机地交换List集合的元素位置 Collections.shuffle(list); sop(list); } } class SLComparator implements Comparator<String>{ public int compare(String s1, String s2) //指定排序方式,字符串长度升序 { if(s1.length() > s2.length()) return 1; else if(s1.length() < s2.length()) return -1; else return s1.compareTo(s2); } }代码分析:Collections还可以对指定的顺序进行强行逆转。
Arrays
Arrays是用于操作数组的工具类,他里面的方法也全部是静态的,不需要创建对象。
/* * Arrays:用于操作数组的工具类 * 里面都是静态方法 * */ import java.util.Arrays; import java.util.List; public class ArraysDemo { public static void sop(Object obj) { System.out.println(obj); } public static void main(String[] args) { // TODO Auto-generated method stub String[] arr = {"abd","de","aa"}; //把数组变成List集合,优点在于:可以使用集合的思想和方法来操作数组中的元素 List<String> list = Arrays.asList(arr); //操作泛型的方法都是类对象 sop("contains(aa) = "+ list.contains("aa")); //list.add("aa"); //注意:将数组变成集合后,不可以使用集合的增删方法。因为数组长度是固定的。 //如果进行了增删操作,那么会发生“不支持操作”异常 sop(list); int[] nums = {1,2,3}; //将基本数据类型的数组转成集合 List<int[]> li = Arrays.asList(nums); sop(li); Integer[] num = {1,2,3}; //将引用类型的数组转成集合 List<Integer> l = Arrays.asList(num); sop(l); /* * 如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素 * 如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在 * */ /*测试结果*/ /*contains(aa) = true [abd, de, aa] [[I@106d69c] [1, 2, 3] */ } }
把数组变成List集合的好处:可以使用集合的思想和方法来操作数组中的元素。
集合变数组
使用Collection接口中的toArray方法。
/* * 集合变数组 * Collection接口中的toArray方法 * 将集合元素转变成数组形式 * */ import java.util.*; public class ToArrayDemo { public static void sop(Object obj) { System.out.println(obj); } public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<String> al = new ArrayList<String>(); al.add("ascde"); al.add("ascde"); al.add("ascde"); /* * 1、指定类型的数组到底要定义多长? * 当指定类型的数组长度小于了集合size,那么该方法内部会创建一个新的数组 * 长度为集合的size;当指定类型的数组长度大于了集合的size,就不会新建数组, * 而是使用传递进来的数组。所以创建一个刚刚好的数组是最优的。 * 2、为什么要将集合变成数组? * 为了限定对元素的操作。 * 不需要进行增删操作,数组的size是不可变的*/ String[] st = al.toArray(new String[al.size()]); sop(Arrays.toString(st)); //[ascde, ascde, ascde] } }Java新特性
高级for循环:
格式:
for(数据类型 变量:被遍历的集合或数组 ){执行语句}
说明:
其一、对集合进行遍历,只能获取集合元素,但是不能对集合进行操作,可以看做是迭代器的简写形式;
其二、迭代器除了遍历,还可以进行remove集合中的元素动作,如果使用ListIterator,还可以在遍历过程中对集合进行增删改查。
普通for循环和高级for循环的区别:
高级for循环有一个局限性,必须有被遍历的目标(集合或数组);
普通for循环遍历数组时有索引。建议在遍历数组的时候,还是希望使用传统for循环,因为可以定义脚标
import java.util.*; /* * 高级for循环 * */ public class ForDemo { public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<String> al = new ArrayList<String>(); al.add("ascde"); al.add("ascde"); al.add("ascde"); /* Iterator<String> it = al.iterator(); while(it.hasNext()) System.out.println(it.next()); */ for(String s : al) { s = "kk"; System.out.println(s); } System.out.println(al); int[] aa = {1,2,3,4}; for(int a : aa) //for 循环除了遍历集合,还可以遍历基本数据类型的数组 { System.out.println(a); } HashMap<Integer, String> hm = new HashMap<Integer,String>(); hm.put(1,"a"); hm.put(2,"a"); hm.put(3,"a"); Set<Integer> keySet = hm.keySet(); for(Integer i:keySet) { System.out.println(i+"-->"+hm.get(i)); } for(Map.Entry<Integer,String> me : hm.entrySet()) { System.out.println(me.getKey()+"--->"+me.getValue()); } } }方法的可变参数
如果一个方法在参数列表中传入多个参数,但个数不确定时,就可以使用可变参数。
可变参数,其实就是数组参数的简写,不用每一次都手动地建立数组对象,只要将要操作的元素作为参数传递即可,隐式将这些参数封装成了数组。
/* * 方法的可变参数使用时: * 可变参数一定要定义在参数列表的最后面*/ public class VariableDemo { public static void main(String[] args) { // TODO Auto-generated method stub show(2,3,4,4); show(); } public static void show(int ... a) //把[]变成了... { System.out.println(a.length); } /* public static void show1(int[] a) //每次都有定义一个数组,作为参数传递 { } */ }静态导入
没加static导入的是类,加上static导入的全是某一个类中的静态成员,这样在调用该类的静态方法时可以不用再写类名。
需要注意的是:当导入的两个类中有同名成员时,需要在成员前加上相应的类名;当类名重名时,需要制定具体的包名。
/* * 静态导入: * 当类名重名时,需要指定具体的包名 * 当方法重名时,需要指定所属的对象或者类 * */ import java.util.*; import static java.util.Arrays.*; //导入的是Arrays这个类的所有静态成员 import static java.lang.System.*; public class StaticDemo { public static void main(String[] args) { // TODO Auto-generated method stub int[] arr = {3,1,2}; //Arrays.sort(arr); sort(arr); //int index = Arrays.binarySearch(arr, 2); int index = binarySearch(arr, 2); out.println(Arrays.toString(arr)); //当方法重名时,需要用类名区分 out.println(index); } }算法部分分析
排序算法:选择排序、冒泡排序等等
/* * 代码演示数组排序:各种排序算法实现 * * 最优的排序方法是希尔排序,原因在于:希尔排序并不是真正地在堆内存中交换元素,而是记录交换的脚标 * 简而言之,在堆内存中交换元素,比较消耗资源 * (实践指导:)在实际开发中使用Arrays工具类 * * */ public class Arraysort { public static void main(String[] args) { // TODO Auto-generated method stub int[] array = new int[] { 0, 89, 24, 32, 11, 22, 0 }; // 新建数组对象 sopArray(array); // 输出数组内容 sortArray_bubble(array); // 冒泡排序过程 sopArray(array); // 输出数组内容 } /* * 代码演示数组排序:选择排序算法实现 思路: 1.一般情况下排序的结果是从小到大 2.比较方式:从0脚标位开始,依次和大于0脚标位元素比较 * 3.若符合条件,则交换;反之,不变;直到数组最后一个元素 4.再从1脚标开始,循环继续第二个步骤 * * 选择排序的特点: 其一:从零脚标位开始,依次和之后元素比较;其二:内循环结束一次,最值出现在头脚标位置上;其三:最值出现后,不再参与比较 */ public static void sortArray_choose(int[] array) { for (int x = 0; x < array.length - 1; x++) { for (int y = x + 1; y < array.length; y++) { if (array[x] > array[y]) { /* * int tmp = array[x]; array[x] = array[y]; array[y] = tmp; */ swap(array, x, y); } else ; } } } /* * 代码演示数组排序:冒泡排序算法实现 思路: 1.一般情况下排序的结果是从小到大;2.比较方式:从0脚标位开始,1脚标位元素比较; * 3.若如何条件,则交换;反之,不变; 4.将1脚标和第2脚标元素比较,依次比较相邻元素,直到最后元素 5.重复以上步骤,将相邻元素进行比较 * * 冒泡排序的特点: 其一:相邻元素比较,如果符合条件则交换位置;其二:内循环结束一次,最值出现在最大脚标位置;其三:最值出现后,不再参与比较 */ public static void sortArray_bubble(int[] array) { // [1,5,3,2,6] for (int x = 0; x < array.length - 1; x++) { // 定义内层循环的次数 for (int y = 0; y < array.length - x - 1; y++) { // 定义哪些元素进行比较 if (array[y] > array[y + 1]) { swap(array, y, y + 1); } } } } /* 数组输出函数 */ public static void sopArray(int[] array) { System.out.print("["); for (int index = 0; index < array.length; index++) { if (index != array.length - 1) System.out.print(array[index] + ","); else System.out.println(array[index] + "]"); } } /* 排序算法的共性部分:都需要将数组元素交换位置,提取出交换位置的函数;提高代码复用性 */ public static void swap(int[] array, int a, int b) { // 方法定义中a,b的值为数组脚标 int tmp = array[a]; array[a] = array[b]; array[b] = tmp; } }
查找:二分查找等等
/* * 程序实现了折半查找方法 * */ public class searchDemo { public static void main(String[] args) { // TODO Auto-generated method stub int[] arr = new int[]{1,2,3,4,5,6,7}; System.out.println(halfSearch(arr,8)); } /*折半查找方法二,可返回待插入元素的数组脚标*/ public static int halfSearchTwo(int[] arr, int key){ int min, mid, max; min = 0; max = arr.length-1; while(min<=max){ mid = (min+max)/2; //将方法一种的mid = (min+max)/2语句进行整合 if(key>arr[mid]) min = mid + 1; //假如key不存在于数组中,可能最后min会大于max,即min>max成立 else if(key<arr[mid]) max = mid - 1; //假如key不存在于数组中,可能最后max会小于min,即min>max成立 else return mid; } return -1; //如果想找到待插入的位置,返回min即可 } /*折半查找方法一,提高效率*/ public static int halfSearch(int[] arr, int key){ int min, mid, max; min = 0; max = arr.length-1; mid = (min+max)/2; while(arr[mid]!=key){ //循环控制条件:是否找到key if(key>arr[mid]) min = mid + 1; //假如key不存在于数组中,可能最后min会大于max,即min>max成立 else if(key<arr[mid]) max = mid - 1; //假如key不存在于数组中,可能最后max会小于min,即min>max成立 else ; if(min>max) return -1; //返回-1,表示数组中没有key值 //如果想找到待插入的位置,返回min即可 mid = (min+max)/2; } return mid; } /*常规数组查找法:循环比较数组中的每一个元素,直到找到为止*/ public static int getIndex(int[] arr, int key){ for(int index = 0; index<arr.length; index++){ if(arr[index] == key) return index; } return -1; //若始终没有查找到元素,则返回-1 } }
进制转换:
/* * 需求: * 进制之间的转换 * */ public class ConversionDemo { public static void main(String[] args) { // TODO Auto-generated method stub toHex(-16); } public static void toBin(int num) { conversion(num, 1, 1); } public static void toOct(int num) { conversion(num, 7, 3); } public static void toHex(int num) { conversion(num, 15, 4); } public static void conversion(int num, int diwei, int yiwei) { if (num == 0) { System.out.println("num=" + 0); return; } // 定义一个包含二进制、八进制、十六进制的表 char[] chs = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; // 定义临时数组,用于装载结果 char[] arr = new char[32]; int pos = arr.length; // 数组长度 32 while (num != 0) { arr[--pos] = chs[num & diwei]; // 末尾位置的坐标为31 num >>>= yiwei; } for (int x = pos; x < arr.length; x++) System.out.print(arr[x]); System.out.println(); } }
相关文章推荐
- Java程序员必须掌握的8大排序算法
- 【转】MYSQL DBA知识了解-面试准备
- 闲着没事做:程序员的核心竞争力是什么?为什么?
- 培训机构毕业的程序员被歧视的背后逻辑
- 作为码农,我们为什么要写作
- 【备战面试之】三、依赖注入是什么?
- 近5年133个Java面试问题列表
- 大龄程序员的未来在何方
- Java 程序员们值得一看的好书推荐
- SQL Server DBA面试知识点(二)-- Recovery Mode
- SQL Server DBA面试知识点(一)--SQL Server的事务隔离级别详解
- .net面试问答(大汇总)
- 禅道程序员的10条原则
- android码农神器 偷懒工具 android懒人框架 LoonAndroid 3 讲解
- android码农神器 偷懒工具 android懒人框架 LoonAndroid 3 讲解
- 是程序员就去Leetcode刷题吧
- 有人认为,“中文编程”是解决中国程序员效率的秘密武器,请问它是一个“银弹”么?
- 程序员也要写文章:好处不止多赚钱
- 我在面试机器学习、大数据岗位时遇到的各种问题
- 关于职业发展的想法