大O符号(big-O notation)
-
大O符号描述了当数据结构里面的元素增加的时候,算法的规模或者是性能在最坏的场景下有多么好。
大O符号也可用来描述其他的行为,比如:内存消耗。因为集合类实际上是数据结构,我们一般使用大O符号基于时间,内存和性能来选择最好的实现。大O符号可以对大量数据的性能给出一个很好的说明。同时,大O符号表示一个程序运行时所需要的渐进时间复杂度上界。
其函数表示是:
对于函数f(n),g(n),如果存在一个常数c,使得f(n)<=c*g(n),则f(n)=O(g(n));
大O描述当数据结构中的元素增加时,算法的规模和性能在最坏情景下有多好。
大O还可以描述其它行为,比如内存消耗。因为集合类实际上是数据结构,因此我们一般使用大O符号基于时间,内存,性能选择最好的实现。大O符号可以对大量数据性能给予一个很好的说明。
数组(Array)和列表(ArrayList)的区别及使用场景
- 区别:Array可以包含基本数据类型和对象类型,ArrayList只能包含对象类型;Array大小固定,ArrayList大小动态变化;ArrayList提供更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
- 场景:处理固定大小时用Array(限于多为查找操作),动态用ArrayList(限于多为查找操作),多为增删改操作用LinkedList(底层是链表)。
java.util.ArrayList < E > 的一些方法 | 描述 |
---|---|
ArrayList() | 构造函数,创建一个空的列表, size为0 |
add(y:E): void | 在list的末尾添加一个元素y |
add(index:int,y:E):void | 在指定的index处插入元素y |
clear(): void | 从list中删除所有元素 |
contains(y: Object): boolean | 如果list含有元素y,返回true |
get(index: int): E | 返回指定index处的元素 |
indexOf(y: Object): int | 返回list中第一个匹配元素的index |
isEmpty(): boolean | 如果list不含元素,返回true |
lastIndexOf(y: Object): int | 返回list中最后一个匹配元素的index |
remove(y: Object): boolean | 删除list中的第一个元素y,如果元素被删除,返回true |
size(): int | 返回list中元素个数 |
remove(index: int): boolean | 删除指定index处的元素,如果元素被删除,返回true |
set(index: int, y: E): E | 设置指定index处的元素为y |
- 数组和ArrayList的比较
操作 | Array | ArrayList |
---|---|---|
创建 array/ArrayList | String[] a = new String[10] | ArrayList list = new ArrayList<>(); |
访问一个元素 | a[index] | list.get(index); |
更新一个元素 | a[index] = “London”; | list.set(index, “London”); |
返回大小 | a.length | list.size(); |
排序 | java.util.Arrays.sort(array) | java.util.Collections.sort(arraylist) |
添加一个新元素 | 很麻烦 | list.add(“London”); |
插入一个新元素 | 很麻烦 | list.add(index, “London”); |
删除一个元素 | 很麻烦 | list.remove(index); |
删除一个元素 | 很麻烦 | list.remove(Object); |
删除所有元素 | 没有 | list.clear(); |
值传递和引用传递
-
看了一篇博客真的讲的很精彩,这里推荐给大家:这一次,让你彻底明白Java的值传递和引用传递!
-
我自己再总结一下,Java中值传递是针对基本变量而言的,传递的是值的拷贝,引用传递其实是把实参地址的拷贝传递给了形参,导致形参变量也指向实参变量地址,传递的并不是对象本身,所以一般对引用对象操作会改变对象本身,一般认为,java内的传递都是值传递.
package basis;
/**
* 值传递,引用传递
* @author shulinYuan Email:2762954662@qq.com
*
*/
public class Demo06 {
public static void main(String[] args) {
int a = 5;
//值传递
change1(a);
System.out.println(a);//a=5
//引用传递
StringBuffer str = new StringBuffer("Hello");
change2(str);
System.out.println(str);//Hello World!
//引用传递,但是并没有改变str值,如果改变应该为//Hello World! World!
change3(str);
System.out.println(str);//Hello World!
}
public static void change1(int x) {
x = x +1;
}
public static void change2(StringBuffer stBf) {
stBf.append(" World!");
}
public static void change3(StringBuffer stBf) {
stBf = new StringBuffer();
stBf.append(" World!");
}
}
为什么会出现4.0-3.6=0.40000001这种现象?
-
原因简单来说是这样:2进制的小数无法精确的表达10进制小数,计算机在计算10进制小数的过程中要先转换为2进制进行计算,这个过程中出现了误差。
-
把3.6转成2进制你会发现是无限循环小数(转一下你就明白了)
-
十进制小数转二进制方法
0.8125的二进制
0.8125*2=1.625 取整是1
0.625*2=1.25 取整是1
0.25*2=0.5 取整是0
0.5*2=1.0 取整是1
即0.8125的二进制是0.1101(第一次所得到为最高位,最后一次得到为最低位)
十进制的数在内存中的存储
-
以补码形式存储
-
原因:
-
补码可以表示-128127的255个有符号数,而原码和反码只能表示-127127的254个有符号数,因为0会出现重码(-0和0)
-
补码还有很多特性,这些特性为符号数的运算提供了方便。(而且有些特性“原码”和“反码”是不具备的)
补码定义:正数的补码与原码相同;负数的补码是对其原码逐位取反,但符号位除外;然后整个数加1。
[X]补:表示X的补码
|X|:表示X的绝对值
当X < 0 时[X]补 = 2~8 - |X|;
当X >=0 时[X]补 = |X| =X;
1) [X+Y]补 = [X]补 +[Y]补
2) [X-Y]补 = [X]补 - [Y]补 = [X]补 + [-Y]补
3) [X*Y]补=[X]补*[Y]补 (乘数(被乘数)相乘的补码等于补码的相乘。)
4) 正数的补码取反加1后,为其对应的负数的补码;负数的补码取反加1后为其绝对值的补码。
即:X>=0:[ [-X]补 ]补 = |X| = X
X<0 [ [X]补]补 = |X| = -X
等等…… -
符号“==”比较的是什么?
- 对于基本数据类型,“==”比较的是数值,只要两个变量的值相等,就返回true;对于引用类型(对象类型)比较的是两个变量是否指向同一个对象,如果是返回true
- equals()方法是Object类提供的一个实例方法,只有引用变量才有,判断两个对象是否相等的标准和“==”一样;但是在String类中以经重写该方法,所以只要两个字符串包含的字符序列相同,equals()就返回true
package basis;
/**
* "==",equals()
* @author shulinYuan
* @Email:2762954662@qq.com
*/
public class Demo07 {
public static void main(String[] args) {
int a = 97;
char b = 'a';
float c = 97.0f;
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(a==b);//true
System.out.println(a==c);//true
System.out.println(c==b);//true
System.out.println(str1==str2);//false
System.out.println(str1.equals(str2));//true
}
}