数据结构-数组
**
数组
**
1初始化数组
1.Java 数组初始化的两种方法:
静态初始化: 程序员在初始化数组时为数组每个元素赋值;
动态初始化: 数组初始化时,程序员只指定数组的长度,由系统为每个元素赋初值。
public static void main(String[] args) {
//静态初始化数组:方法一
String cats[] = new String[] {“Tom”,“Sam”,“Mimi” };
//静态初始化数组:方法二
String dogs[] = {“Jimmy”,“Gougou”,“Doggy”};
//动态初始化数据
String books[] = new String[2];
books[0] = “Thinking in Java”;
books[1] = “Effective Java”;
System.out.println(cats.length);
System.out.println(dogs.length);
System.out.println(books.length);
}
Java数组是一种引用数据类型。数组变量并不是数组本身,而是指向堆内存中存放的数组对象。因此,可以改变一个数组变量所引用的数组。看下面这段代码:
public static void main(String[] args) {
//静态初始化数组:方法一
String cats[] = new String[] { "Tom","Sam","Mimi"};
//静态初始化数组:方法二
String dogs[] = {"Jimmy","Gougou","Doggy"};
//动态初始化数据
String books[] = new String[2];
books[0] = "Thinking in Java";
books[1] = "Effective Java";
cats = dogs;
books = dogs;
}
2.数组是否必须初始化
对于这个问题,关键在于要弄清楚数组变量和数组对象的差别。数组变量是存放在栈内存中的,数组对象是存放在堆内存中的。数组变量只是一个引用变量,他能够指向实际的数组对象。
所谓的数组初始化并非对数组变量初始化,而是对数组对象进行初始化。
2 foreach
首先说一下foreach有的也叫增强for循环,foreach其实是for循环的一个特殊简化版。
再说一下foreach的书写格式:
for(元素类型 元素名称 : 遍历数组(集合)(或者能进行迭代的)){
语句
}
foreach虽然是for循环的简化版本,但是并不是说foreach就比for更好用,foreach适用于循环次数未知,或者计算循环次数比较麻烦情况下使用效率更高,但是更为复杂的一些循环还是需要用到for循环效率更高。
我们看看下面的例子:
1 public static void main(String[] args) {
2 List<String> arr = new ArrayList<String>();
3 arr.add("你好");
4 arr.add("我好");
5 arr.add("大家好");
6
7 //foreach循环
8 for(String str : arr){ //这里的str就是为了获取每次循环的arr中的值
9 System.out.println(str); //就相当于 String str=arr[i]
10 }
11 }
但是相比较之下我们用for循环输入就略显麻烦
public static void main(String[] args) {
List<String> arr = new ArrayList<String>();
arr.add("你好");
arr.add("我好");
arr.add("大家好");
//for循环
for(int i=0;i<arr.size();i++){
System.out.println(arr.get(i)); //要获取list中元素需要用get方法
}
}
除了这种普通的集合还可以对像map这种键值对使用
例如:
public static void main(String[] args) {
Map<String,String> mapstr = new HashMap<String,String>();
mapstr.put("王", "男");
mapstr.put("李", "男");
mapstr.put("张", "女");
//entrySet方法是为了获取键值对的集合
for(Map.Entry<String, String> s : mapstr.entrySet()){ //这里的Map.Entry<String, String>其实就是一个类型 用来表示键值对的类型
System.out.println("key="+s.getKey()); //这里其实还是相当于 s=maostr.entrySet,只不过s存储的是键值对。
System.out.println("value="+s.getValue()); //所以可以用get方法获取出来存储的键值对。
}
}
另外foreach不支持在循环中添加删除操作,因为在使用foreach循环的时候数组(集合)就已经被锁定不能被修改,否则会报出java.util.ConcurrentModificationException异常
例如:
public static void main(String[] args) {
List<String> arr = new ArrayList<String>();
arr.add("你好");
arr.add("我好");
arr.add("大家好");
//foreach循环
for(String str : arr){
System.out.println(str);
arr.add("1"); //对arr进行添加
}
}
关于不能添加删除原理以及如何在foreach中添加删除我们下篇再说。
所以总结如下:
**foreach适用于只是进行集合或数组遍历,for则在较复杂的循环中效率更高。
foreach不能对数组或集合进行修改(添加删除操作),如果想要修改就要用for循环。
所以相比较下来for循环更为灵活。
3 自定义类型的数组 默认为null
增删改查
public class MyArray {
private long[] arr;
//表示有效数据的长度
private int elements;
public MyArray(){
arr = new long[50];
}
public MyArray(int maxsize){
arr = new long[maxsize];
}
/**
*功能描述:添加数据
*@param:
*@return:
*@author: liuhaidong
*@date:
*/
public void insert(long value){
arr[elements] = value;
elements ++;
}
/**
*功能描述:显示数据
*@param:
*@return:
*@author: liuhaidong
*@date:
*/
// public void display(){
// System.out.println("[");
// for(long arrArray : arr){
// System.out.println(arrArray+",");
// }
// System.out.println("]");
// }
public void display(){
System.out.println("[");
for(int i=0;i<elements;i++)
{
System.out.println(arr[i] +"");
}
System.out.println("]");
System.out.println("当前elements个数为:"+elements);
}
/*
* @Author liuhaidong
* @Description 查找数据
* @Date 10:28 2019/9/15 0015
* @Param
* @return
**/
public int search(long value){
int i;
for(i=0;i<elements;i++)
{
if(value ==arr[i]){
break;
}
}
if(i ==elements){
return -1;
}else {
return i;
}
}
/*
* @Author liuhaidong
* @Description 查找数据,根据索引来查
* @Date 10:30 2019/9/15 0015
* @Param
* @return
**/
public long get(int index){
if(index >elements || index <0)
{
throw new ArrayIndexOutOfBoundsException();
}else {
return arr[index];
}
}
/*
* @Author liuhaidong
* @Description 删除数据
* @Date 10:32 2019/9/15 0015
* @Param
* @return
**/
public void delete(int index){
if(index >= elements || index <0){
throw new ArrayIndexOutOfBoundsException();
}else {
for (int i =index;i < elements;i++){
arr[i] = arr[i +1];
}
elements --;
}
}
/*
* @Author liuhaidong
* @Description 更新数据
* @Date 11:09 2019/9/15 0015
* @Param
* @return
**/
public void change(int index,int newvalue)
{
if(index >=elements || index <0){
throw new ArrayIndexOutOfBoundsException();
}else {
arr[index] = newvalue;
}
}
/*
* @Author liuhaidong
* @Description 添加有序数据
* @Date 11:22 2019/9/15 0015
* @Param
* @return
**/
public void insertOrderedArray(long value){
int i;
for(i =0;i<elements;i++){
if(arr[i] > value){
break;
}
}
for(int j =elements;j > i;j--){
arr[j] = arr[j -1];
}
arr[i] = value;
elements ++;
}
/*
* @Author liuhaidong
* @Description 二分查找数据
* @Date 11:42 2019/9/15 0015
* @Param
* @return
**/
public int binarySearch(long value){
int middle = 0;
int low = 0;
int pow = elements;
while(true){
middle = (pow +low) / 2;
if(arr[middle] == value)
{
return middle+1;
}else if(low >pow)
{
return -1;
}else {
if(arr[middle] > value){
pow = middle -1;
}else {
low = middle +1;
}
}
}
}
主函数
public class Main {
public static void main(String[] args) {
// MyArray myArray = new MyArray();
// myArray.insert(13);
// myArray.insert(14);
// myArray.insert(15);
// myArray.display();
// myArray.change(0,17);
// myArray.display();
System.out.println(myArray.search(17));
System.out.println(myArray.get(2));
// myArray.delete(2);
// myArray.display();
MyArray myArray = new MyArray();
myArray.insertOrderedArray(16);
myArray.insertOrderedArray(13);
myArray.insertOrderedArray(14);
myArray.insertOrderedArray(15);
myArray.insertOrderedArray(17);
myArray.display();
System.out.println(myArray.binarySearch(16));
}
}