其实编写程序就是把数据拿在手中玩儿,对不?
Java用来干嘛?
编写程序!程序又拿来干嘛?处理现实中的问题?什么问题?一系列复杂的逻辑,运算等!
其实,程序的功能就是为现实生活中遇到的问题进行服务。
为企业进行服务,处理数据,一切都是以数据为中心开展的活动!
数据才是核心!!!
既然数据如此重要,程序中如何处理各种数据呢?-------使用容器
处理数据时使用容器能够有效的对数据进行管理,非常方便!
必须滚瓜烂熟的掌握容器!!!
Java中用来存放数据的容器,各自有自身的特性,适用于不同的场景!
第一种:数组
一维数组
二维数组
第二种:集合
List集合
Set集合
Map集合
=============================================================
数组的常见操作
求最值
public class Test {
/**
* 求数组中的最大值
* @param args
*/
public static void main(String[] args) {
//静态初始化一个int类型的数组,
int[] arr = {-1,5,-2,8,3,0};
int maxElement = getMax(arr);
System.out.println("maxElement="+maxElement);
System.out.println("maxElement="+getMax2(arr));
}
/**
* 第一种思路:每次记录最大的数
* @param arr
* @return
*/
public static int getMax(int[] arr) {
//数组的第一个元素
int maxElement = arr[0];
for(int i=1; i<arr.length; i++) {
if(arr[i] > maxElement)
maxElement = arr[i];
}
return maxElement;
}
/**
* 第二种思路:每次记录最大数在数组中的角标位
* @param arr
* @return
*/
public static int getMax2(int[] arr) {
//数组的第一个角标
int maxElementIndex = 0;
for(int i=1; i<arr.length; i++) {
if(arr[i] > arr[maxElementIndex]) {
maxElementIndex = i;
}
}
return arr[maxElementIndex];
}
}
数组的排序
【这里只是演示排序的思想,实际开发中不要用选择与冒泡进行排序,因为效率太低】
选择排序
原理:每次都以某个角标位为基准与后面的所有数进行比较。
实际上就是以角标为中心,每次把该角标上的数与后面的所有数进行比较。
选择排序,其特点是完全按照线性顺序逐个比较元素的,啃着1个位置与其它元素比较。
如,0号位元素,先与1号位元素比,发现1号位的元素更小,它们交互位置
交互位置后,0号位元素存放的是小值,
然后,再拿0号位这个'最小值'与2号位比较。。。
import java.util.Arrays;
public class SelectSort {
public static void main(String[] args) {
int[] arr = new int[]{100,3,1,39,6,7,2};
sort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 以升序为例
* 第1次:数组的0角标位始终用来存放最小值(每次比较如果有比它小的,则交换位置,将小的数放到0角标,然后再逐个与后面的数比较)
* 第2次,数组的1号角标位又用来存放后面这些数中最小的那个值
* 依次类推
* 当角标位等于数组长度减2时,进行最后一次比较,即数组最后2个数之间比较
* @param arr
*/
private static void sort(int[] arr) {
//外层:锁定每次排序用来存储最值的角标
//当i=arr.length-1的时候,实际已经为数组的最后一个元素了,一个数无需再比较了
for (int i = 0; i < arr.length-1; i++) {
//内层:逐个比较,得到一个最值(最后1次比较时,j=arr.length-1)
for (int j = i+1; j < arr.length; j++) {
//后面的数更小,则交互位置
if(arr[j] < arr[i]) {
arr[j] = arr[j] ^ arr[i];
arr[i] = arr[j] ^ arr[i];
arr[j] = arr[j] ^ arr[i];
}
}
}
}
}
优化选择排序
优化结果:减少数据交换位置的动作,每次遍历后都只对锁定角标位上的值与最值进行交换
import java.util.Arrays;
public class SelectSortImprove {
public static void main(String[] args) {
int[] arr = new int[]{10,3,9,-1,8,7,6,5,4,3,2,1};
sort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 选择排序的改进
* 改进的地方:
* 每次比较出最小值,不立刻交换位置
* 而是记录最小值的角标,再拿这个角标的值与其它元素进行比较
* 一次遍历,得到最小值的角标,再与数组中锁定的角标位进行值的交换动作
* @param arr
*/
public static void sort(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
int minElementIndex = i;
for (int j = i+1; j < arr.length; j++) {
if(arr[minElementIndex]>arr[j]) {
minElementIndex = j;
}
}
if(i != minElementIndex)
swap(arr,i,minElementIndex);
}
}
private static void swap(int[] arr, int i, int minElementIndex) {
arr[i] = arr[i] ^ arr[minElementIndex];
arr[minElementIndex] = arr[i] ^ arr[minElementIndex];
arr[i] = arr[i] ^ arr[minElementIndex];
}
}
冒泡排序
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] arr = new int[]{10,9,8,7,6,5,4,3,2,1};
sort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 冒泡排序
* 特点:相邻元素逐个比较
* 一次遍历之后,大数都尽量往后靠了,并且最大的数放到了最后
* @param arr
* @return
*/
private static void sort(int[] arr) {
//外层:决定内层循环的次数
for (int i = 0; i < arr.length-1; i++) {
//内层:比较相邻的元素
//-1 是为了防止角标越界
//-i是参与比较的元素递减
for (int j = 0; j < arr.length-i-1; j++) {
//升序
if(arr[j]>arr[j+1]) {
arr[j] = arr[j] ^ arr[j+1];
arr[j+1] = arr[j] ^ arr[j+1];
arr[j] = arr[j] ^ arr[j+1];
}
}
}
}
}
开发中这样排序
public static void main(String[] args) {
//数组中元素的排序
int[] arr = new int[]{10,9,8,7,6,5,4,3,2,1};
//Arrays类提供了针对数组操作的方法
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//集合中元素的排序
List<BigDecimal> list = new ArrayList<BigDecimal>();
list.add(new BigDecimal(100.1));
list.add(new BigDecimal(20));
list.add(new BigDecimal(88.8));
//Collections类提供了对集合的排序(集合中的元素如果没有实现Comparable接口,则需要手动指定一个比较器)
//BigDecimal extends Number implements Comparable<BigDecimal>
Collections.sort(list);
for(BigDecimal b : list) {
System.out.println(b.doubleValue());
}
}
数组中的查找
无序数组中查找元素
public class ArraySearch {
/**
* 无序数组的查找
* @param args
*/
public static void main(String[] args) {
int[] arr = {1,5,2,7,4,0};
int key = 5;
int index = searchElement(arr,key);
System.out.println(key+"在数组arr中的角标位:"+index);
}
private static int searchElement(int[] arr, int key) {
for(int i=0; i<arr.length; i++) {
//无序数组的查找,只能挨个比较
if(arr[i] == key)
return i;
}
return -1;
}
}
有序数组的查找
基于有序的特点,可以提高查找效率
由于数组有序,以升序为例,不用挨个比较,可以跳跃着比较,因为数组已经有序
【不要为了使用二分查找而对一个数组进行排序!这样已经没意义了,因为数组都变了!~】
被操作的数组前提是有序的(升序/降序),在此基础上才能使用二分查找法!
public class ArraySearch {
/**
* 有序数组的查找
* @param args
*/
public static void main(String[] args) {
int[] arr = {1,3,5,7,9};
int key = 5;
int index = binarySearch(arr,key);
System.out.println(key+"在数组arr中的角标位:"+index);
}
private static int binarySearch(int[] arr, int key) {
int min = 0, max = arr.length-1, mid = (min+max)>>1;
//循环结束的条件:min 大于 max,再比较已经没有意义,循环结束
while(min <= max) {
if(arr[mid] < key) {
//中间数 < key,移动min角标,指向mid的后一位
min = mid + 1;
} else if(arr[mid] > key) {
// 中间数 > key,移动max角标,指向mid的前一位
max = mid - 1;
} else {
return mid;
}
//如果没有找到,从新定位mid的位置
mid = (min+max)>>1;
}
return -1;
}
}
开发中对有序数组这样查找
import java.util.Arrays;
public class ArraySearch {
/**
* 使用Arrays类中的binarySearch方法对有序数组进行查找
* @param args
*/
public static void main(String[] args) {
int[] arr = {1,3,5,7,9};
int key = 2;
//binarySearch()对数组进行查找,底层做了2个操作
//1.如果查找到,则返回元素的角标
//2.如果没有找到,则告诉你该元素应该插入到数组的哪个位置(插入后数组仍有序):
// index: -(insertion point) -1 ,既保证不存在时返回负数,又能明确了插入位置
int index = Arrays.binarySearch(arr, key);
System.out.println(key+"在数组arr中的角标位:"+index);
//返回-2
//表示数组中没有2这个元素,而且如果要插入到数组中,其角标位是 |(-2 + 1)| = 1
}
}
数组的应用---进制转换---把数组当做一张表来使用
/**
* 数组的灵活运用
* 查表法
* 一组数与另一组数有对应关系,则用数组来操作,用一个数组定义一个对应关系表
* 如果有对应关系,但是不连续,则用Map
* 其实这里的数组是一个特殊的Map,其key就是数组的角标
* 而这个key就是程序中运算的结果,这样,直接从数组中取即可!
* @param args
*/
public class ArrayUse {
/**
使用数组定义一张映射关系表---10进制数与16进制的对应关系
玄机:转换为得到的10进制数与对应的16进制字符在表中的角标相同
*/
static char[] hexTable = {'0','1','2','3','4',
'5','6','7','8','9',
'A','B','C','D','E'};
public static void main(String[] args) {
int num = 0;
char[] retHex = toHex(num);
for(char c : retHex) {
if( Character.isDigit(c) || Character.isLetter(c) )
System.out.print(c);
}
}
public static char[] toHex(int num) {
//32位系统上,最多就是8个16进制 (32/4=8)
int len = 8;
//从数组的最后一位开始存,后面就不需要反转数组了
int pos = len -1;
//定义一个用来存放转换后结果的数组
char[] hexResult = new char[len];
//do... whlie()保证至少执行一次,这样保证num==0的情况下也有结果
do{
// 15 的 2进制 : 1111,将最后4位与1111进行与
int temp = num & 15;
//使用temp作为角标到表中查找对应的16进制字符
hexResult[pos--] = hexTable[temp];
// 取下一组4个比特位的数
num = num >>> 4;
} while(num != 0);
return hexResult;
}
}
10进制与其它进制的转换(整合)
public class ArrayUse {
/**
使用数组定义一张映射关系表---10进制数与16进制的对应关系
玄机:转换为得到的10进制数与对应的16进制字符在表中的角标相同
*/
static char[] baseTable = {'0','1','2','3','4',
'5','6','7','8','9',
'A','B','C','D','E'};
/**
使用枚举存储进制类型
各进制中有一个属性:10进制转换为该进制每次移动的位数
*/
static enum Base {
binary(1),octal(3),hex(4);
private int offset;
private Base(int offset) {
this.offset = offset;
}
}
public static void main(String[] args) {
int num = 60;
int base = 2;
char[] convert = numberConvert(num, base);
for(char c : convert) {
if( Character.isDigit(c) || Character.isLetter(c) )
System.out.print(c);
}
}
/**
*
* @param num 需要进制转换的数
* @param base 进制
* @param offset 每次左移的位数
* @return
*/
public static char[] numberConvert(int num, int base) {
//32位系统
int len = 32;
//从数组的最后一位开始存,后面就不需要反转数组了
int pos = len -1;
//定义一个用来存放转换后结果的数组
char[] hexResult = new char[len];
int offset = getOffestByBase(base);
if(offset == -1) {
throw new RuntimeException("指定的进制错误");
}
//do... whlie()保证至少执行一次,这样保证num==0的情况下也有结果
do{
int temp = num & (base-1);
//使用temp作为角标到表中查找对应的16进制字符
hexResult[pos--] = baseTable[temp];
// 取下一组4个比特位的数
num = num >>> offset;
} while(num != 0);
return hexResult;
}
private static int getOffestByBase(int base) {
switch(base) {
case 2: return Base.binary.offset;
case 8: return Base.octal.offset;
case 16: return Base.hex.offset;
}
return -1;
}
}
开发中这样使用进制转换
public static void main(String[] args) {
int num = 60;
//转为2进制
System.out.println(Integer.toBinaryString(num));
//转为8进制
System.out.println(Integer.toOctalString(num));
//转为16进制
System.out.println(Integer.toHexString(num));
}