thinking in java (九) ----- 数组之二(Array)

性能

在java中有一系列的方式可以用来作为存放对象的容器,并且有很多在操作上比数组要简单。但是我们仍然会使用数组。因为数组有自己的优点,效率,类型和保存基本类型的能力。在java中,数组是效率最高的存储和随访问对象引用序列的方式。

在一般的项目中,确实数组是咩有List,Map等集合使用方便,但有时候也是会用到的。

public class Main{
	public static void main(String[] args) {
		int sum = 0;
		int [] arrays = new int [1000001];
		Long time1 = System.currentTimeMillis();
        for(int i = 0 ; i < 1000000 ;i++){
            arrays[i] = i;
            sum += arrays[i]; 
        }
        Long time2 = System.currentTimeMillis();
        System.out.println("数组求和所花费时间:" + (time2 - time1) + "毫秒"+sum);
        
        int sum1=0;
        ArrayList<Integer> list = new ArrayList<>();
        Long time3 = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++) {
            list.add(i);
            sum1 +=  list.get(i);
        }
      
        Long time4 = System.currentTimeMillis();
        System.out.println("List求和所花费时间:" + (time4 - time3) + "毫秒"+sum1);
	}	
}
————————————————————————
数组求和所花费时间:4毫秒1783293664
List求和所花费时间:49毫秒1783293664

说明性能这一块儿,数组还是猛一些。但明显可以看出受限制比较多,比如说必须先定义数组长度。在list集合中,求和有一个list.get(i),这个动作是拆箱动作,Integer对象转换为一个int基本类型,这里就产生了很多消耗。

所以在性能优先的时候可以考虑数组

arraycopy

java提供了一个System.arraycopy()的static函数,和for循环比较,这个函数能够更快速的进行复制数组,System.arraycopy()被重载以处理所有的类型,其语法:

public static void arraycopy(Object src,
                             int srcPos,
                             Object dest,
                             int destPos,
                             int length)
--------------------- 

其中:src表示源数组,srcPos表示源数组要复制的起始位置,desc表示目标数组,length表示要复制的长度。
直接举例:

arrayCopy( arr1, 2, arr2, 5, 10);

意思是;将arr1数组里从索引为2的元素开始, 复制到数组arr2里的索引为5的位置, 复制的元素个数为10个. 。

来看一段代码

public class Main{
	public static void main(String[] args) {
//		 User [] users=new User[]{new User(1,"admin","[email protected]"),new User(2,"maco","maco@qq,com"),new User(3,"kitty","kitty@qq,com")};//初始化对象数组
		User user1 = new User(1,"admin","[email protected]");
		User user2 = new  User(2,"maco","maco@qq,com");
		User [] users = new User[2];
		users[0] = user1;
		users[1] = user2;
		User [] target=new User[users.length];//新建一个目标对象数组
		   System.arraycopy(users, 0, target, 0, users.length);//实现复制
		   System.out.println("源对象与目标对象的物理地址是否一样:"+(users[0] == target[0]?"浅复制":"深复制"));
		   target[0].setEmail("[email protected]");
		   System.out.println("修改目标对象的属性值后源对象users:");
	       for (User user : users){
	    	   System.out.println(user);
		   }	     

	
	}	

}
class User{
	private Integer id;
	private String username;
	private String email;
	//无参构造函数
	public User() {	}
	//有参的构造函数
	public User(Integer id, String username, String email) {
		super();
		this.id = id;
		this.username = username;
		this.email = email;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", email=" + email
				+ "]";
	}

}

运行结果

源对象与目标对象的物理地址是否一样:浅复制
修改目标对象的属性值后源对象users:
User [id=1, username=admin, [email protected]]
User [id=2, username=maco, email=maco@qq,com]

下图是过程

Arrays.equals()

这是一个比较数组是否相同的方法,相同的条件是长度相同,且每一个下标的元素都相等(不是reference),

//基本类型数组
int[] i1 = new int[]{1,2,3,4};
int[] i2 = new int[]{1,2,3,4};
System.out.println(i1.equals(i2));                  //false
System.out.println(Arrays.equals(i1, i2));          //true

//对象数组
Integer[] i3 = new Integer[]{new Integer(1),new Integer(2)};
Integer[] i4 = new Integer[]{new Integer(1),new Integer(2)};
System.out.println(i3.equals(i4));                  //false
System.out.println(Arrays.equals(i3, i4));          //true
--------------------- 
作者:SnailMann 
来源:CSDN 
原文:https://blog.csdn.net/SnailMann/article/details/80333044 
版权声明:本文为博主原创文章,转载请附上博文链接!

因为常规的equals是比较的reference,所以自然是false 。

Arrays.sort()

快速排序

public static void main(String[] args) {
        int[] i1 = new int[]{1,3,2,4};
        Arrays.sort(i1);
        System.out.println(Arrays.toString(i1));

        Integer[] i3 = new Integer[]{new Integer(1),new Integer(3),new Integer(2),new Integer(4)};
        Arrays.sort(i3);
        System.out.println(Arrays.toString(i3));
    }
--------------------- 
[1, 2, 3, 4]
[1, 2, 3, 4]

我们可以看到默认的排序方式是升序的,是从大到小排序的。因为Arrays.sort()没有专门的降序排序的实现,如果是基本类型数组,就从后遍历赋值给另一个数组,如果是对象数组,可以通过实现Comparator方法来完成,比较麻烦一些。 

public class SortDemo {
    public static void main(String[] args) {
        MyComparator comparator = new MyComparator();

        Integer[] i3 = new Integer[]{new Integer(1),new Integer(3),new Integer(2),new Integer(4)};
        Arrays.sort(i3,comparator);
        System.out.println(Arrays.toString(i3));

        //output : [4,3,2,1]
    }

}

class MyComparator implements Comparator<Integer>{

    @Override
     public int compare(Integer o1, Integer o2) {
       //如果o1小于o2,我们就返回正值,如果o1大于o2我们就返回负值,
         //这样颠倒一下,就可以实现反向排序了
         if(o1 < o2) {
            return 1;
         }else if(o1 > o2) {
             return -1;
         }else {
             return 0;
         }
     }
 }

 Arrays.asList()

待续

参考:https://www.cnblogs.com/chenssy/p/3466092.html

猜你喜欢

转载自blog.csdn.net/sinat_38430122/article/details/83345792