Java数组
Java数组定义与初始化的几种方式:1
2
3
4int[] array1 = {1,2,3,4};
int[][] array2 = {{1,2,3},{4,5,6}};
int[] array3 = new int[5];
int[][] array4 = new int[2][3];
关于默认初始化:
1.基本数据类型的数组在创建之后,已经赋默认值 0 (或0L、0.0D、0.0F);
2.引用类型的数组在创建之后,已经赋默认值null.
3.boolean类型默认值为false,Integer类型为null.
Java获取数组各维度的长度:
1 | System.out.println(array1.length); |
Java for-each遍历数组:1
2
3for(int x: array1){
System.out.println(x);
}
Java 数组作为函数参数:
传递的是数组的引用,相当于C中的指针
1 | void test(int[] a) { |
java数组的比较:
1 | int[] array1 = {1, 2, 3, 4}; |
java数组与List的转换(并没有更好的方法):
1 | List<Integer> l = new ArrayList<>(); |
java数组的排序:
1 | //升序排序 |
Java集合框架
整体结构:
ArrayList
List接口是Collection的子接口,用于定义线性表结构,其中ArrayList可以理解为一个动态数组,而LinkedList可以理解为一个链表。
ArrayList的基本操作:
1 | List<Integer> l = new ArrayList<>(); |
ArrayList排序:
1 | //升序排序 |
HashSet
HashSet不能添加重复的元素,当调用add(Object)方法时候,首先会调用Object的hashCode方法判hashCode是否已经存在,如不存在则直接插入元素; 如果已存在则调用Object对象的equals方法判断是否返回true, 如果为true则说明元素已经存在,如为false则插入元素。
先来看看基本数据类型的HashSet实现:
1 | HashSet<Integer> hs = new HashSet<>(); |
对于自定义数据类型的HashSet,需要在类中重写hashCode方法和equals方法,用以判断传入集合的元素是否已经存在。
1 | class people{ |
HashMap
存储键值对采用HashMap实现,具体的方法如下:
1 | HashMap<Integer,String> hm = new HashMap<>(); |
Java队列与栈
栈
java中的栈是Vector的一个子类,它实现了一个标准的后进先出的栈
1 | //栈的定义 |
队列
LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。
1 | //对列的定义 |
优先队列
PriorityQueue是一种基于优先级堆的优先级队列。如果不提供Comparator的话,优先队列中元素默认按自然顺序排列,也就是数字默认是小的在队列头,字符串则按字典序排列,也可以根据 Comparator 来指定,这取决于使用哪种构造方法。优先级队列不允许 null 元素。依靠自然排序的优先级队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException)
1 | //定义优先队列,指定队列初始大小(可选),并自定义排序顺序(可选),这个例子中是按照降序排序 |
Java比较器
Comparable接口
如果一个类中已经实现了Comparable接口,可以直接使用java.util.Arrays类,Collections类,优先队列等进行数组的排序操作。
Comparable接口的定义如下:1
2
3
4
5
6
7
8
9public interface Comparable<T>{
public int compareTo(T o);
}
/*
此方法返回一个int类型的数据,但是此int的值只能是一下三种:
1:表示大于
-1:表示小于
0:表示相等
*/
给出一个具体的例子:
1 | class people implements Comparable<people>{ |
在此例子中,我们可以根据age来定义people的大小关系,比如如果a的age小于a1的age,则定义people a小于people a1(在返回值上反应为-1)。
如果建立people的优先队列,则优先队列的内部情况如下:
1 | people a = new people(1); |
Comparator接口
如果一个类已经开发完成,但是在此类建立的初期并没有实现Comparable接口,此时肯定是无法进行对象排序操作的,所以为了解决这一的问题,java又定义了另一个比较器的操作接口 Comparator 此接口定义在java.util包中,它的定义为:
1 | public interface Comparator<T>{ |
Java字符串
String
字符串常量池
String类是我们平常项目中使用频率非常高的一种对象类型,jvm为了提升性能和减少内存开销,避免字符的重复创建,其维护了一块特殊的内存空间,即字符串池,当需要使用字符串时,先去字符串池中查看该字符串是否已经存在,如果存在,则可以直接使用,如果不存在,初始化,并将该字符串放入字符创常量池中。
基本操作
String类中使用字符数组保存字符串,因为有“final”修饰符,所以可以知道string对象是不可变的。可选的创建方式有直接赋值和new两种方式
使用String直接赋值:
String str = “abc”;可能创建一个或者不创建对象,如果”abc”在字符串池中不存在,会在java字符串池中创建一个String对象(”abc”),然后str指向这个内存地址,无论以后用这种方式创建多少个值为”abc”的字符串对象,始终只有一个内存地址被分配。==判断的是对象的内存地址,而equals判断的是对象内容。通过以下代码测试:
1 | String str = "abc"; |
使用new String 创建字符串:
String str2 = new String(“ABC”);至少创建一个对象,也可能两个。因为用到new关键字,肯定会在heap中创建一个str2的String对象,它的value是“ABC”。同时如果这个字符串再java String池里不存在,会在java池里创建这个String对象“ABC”。
1 | String str = new String("abc"); |
建议在平时的使用中,尽量使用String = “abcd”;这种方式来创建字符串,而不是String = new String(“abcd”);这种形式,因为使用new构造器创建字符串对象一定会开辟一个新的heap空间,而双引号则是采用了String interning(字符串驻留)进行了优化,效率比构造器高。
与其他类型的转换
String转基本数据类型:一般可以直接调用各数据类型包装类的方法:
1 | String x = "123"; |
基本数据类型转String:一般也可以直接调用各数据类型包装类的方法:
1 | int i = 1; |
其他常用方法
1 | String test = "123xyz"; |
StringBuffer
使用StringBuffer的目的在于String的内容不可更改,而它可以。
1 | //新建StringBuffer类 |
类似于StringBuffer的还有StringBuilder。 在字符缓冲区被单个线程使用时优先考虑使用StringBuilder(),效率更高。但StringBuffer对于多线程是安全的。