Scanner类
Scanner类是引用数据类型的一种,我们可以使用该类来完成用户键盘录入,获取到录入的数据。
Scanner使用步骤:
导包:import java.util.Scanner;
创建对象实例:Scanner sc = new Scanner(System.in);
调用方法:
int i = sc.nextInt();
用来接收控制台录入的数字
String s = sc.next(); 用来接收控制台录入的字符串
举例
String s = sc.next();
System.out.println(s);//比如输入5,输出是51(而不是6,因为字符串的+,是连接符)
数组拷贝
一个数组变量拷贝给另一个数组变量,此时,两个变量将饮用同一个数组。
int[] arr1 = {1,2,3,4};
int[] arr2 = arr1;
arr2[1]=0;//arr1[1]也输出0
一个数组所有值拷贝到另一个数组:
int copyarr = Arrays.copy0f(arr,arr.length);
static type copy0f(type[] a, int length);
static type copy0f(type[] a, int start, int end)//包含start,不包含end
二分搜索查找值v
static int binarySearch(type[] a, type v);
static int binarySearch(type[] a, int start, int end, type v)//包含start,不包含end
随机数
Math.random()将返回一个[0,1)之间的随机浮点数,n乘此值,得到[0,n-1]之间的随机数。
对象
Java对象都是在堆上构造的
类
构造器
引用可变对象的访问器方法:
基本数据类型传递与引用传递区别
传递方法参数类型为:
- 8种数据类型,是值传递(call by value)(数字以及布尔值)
- 对象,是引用传递(call by reference)(地址传递)
一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。
即使java函数在传递引用数据类型时,也只是拷贝了引用的值罢了,之所以能修改引用数据是因为它们同时指向了一个对象,但这仍然是按值调用而不是引用调用。
继承
class Subclass-name extends Superclass-name
{
//methods and fields
}
java关键字extends
代替了C++的:
java中所有继承都是公有继承
关键字 super 来覆盖override
public doubkle getSalary()
{
double baseSalary = super.getSalary();//有一点类似this,这里想用到公有接口(父类),所以要用到同一个函数返回值,但是又不能不加super,不然就会无限次调用自己了
return baseSalary + bonus;
}
super代替了C++的::
==和equals比较运算符
泛型数组列表
ArrayList<元素对象类型>
ArrayList<Employee> staff = new ArrayList<>();
泛型方法的类型推断
在调用泛型方法的时候,可以指定泛型类型,也可以不指定。
在不指定泛型类型的情况下,泛型类型为该方法中的几种参数类型的共同父类的最小级,直到Object。
在指定泛型类型的时候,该方法中的所有参数类型必须是该泛型类型或者其子类。
public class Test {
public static void main(String[] args) {
/**不指定泛型的时候*/
int i=Test.add(1, 2); //这两个参数都是Integer,所以T替换为Integer类型
Number f=Test.add(1, 1.2);//这两个参数一个是Integer,另一个是Float,所以取同一父类的最小级,为Number
Object o=Test.add(1, "asd");//这两个参数一个是Integer,另一个是String,所以取同一父类的最小级,为Object
/**指定泛型的时候*/
int a=Test.<Integer>add(1, 2);//指定了Integer,所以只能为Integer类型或者其子类
int b=Test.<Integer>add(1, 2.2);//编译错误,指定了Integer,不能为Float
Number c=Test.<Number>add(1, 2.2); //指定为Number,所以可以为Integer和Float
}
//这是一个简单的泛型方法
public static <T> T add(T x,T y){
return y;
}
}
对象包装器与自动装箱
每段程序只有一个package,相当于路径地址,系统编译要找到程序所在路径,通过package找到,比如package.com.example.demo;
每个.
代表一个文件夹里。
接口
类里面有很多很多方法,可以抽几个方法,做成一个接口,类可以做成很多个接口,到时候使用接口,接口中的方法,比较清楚,而不是用类中的方法,这也是做成接口的好处。
static关键字
static关键字在变量,方法,块和嵌套类中。 static关键字属于类,而不是类的实例。
所有实例数据成员将在每次创建对象时获取内存。某某是所有对象的共同属性。如果使它静态化(使用static关键字修饲),这个字段将只获得内存一次。
Java静态属性被共享给所有对象。
不使用静态变量的计数器程序
在这个例子中,我们创建了一个名为count的实例变量用来统计创建对象的数目,它在构造函数中执行递增。 由于实例变量在创建对象时要获取内存,每个对象都将具有实例变量的副本,如果它被递增了,它也不会反映到其他对象中。所以每个对象在count变量中的值还是1。
class Counter {
int count = 0;// will get memory when instance is created
Counter() {
count++;
System.out.println(count);
}
public static void main(String args[]) {
Counter c1 = new Counter();//1
Counter c2 = new Counter();//1
Counter c3 = new Counter();//1
}
}
计数器静态变量的程序
如上所述,静态变量将只获取一次内存,如果任何对象更改静态变量的值,它将保留其值,所有实例均可访问同一变量值。
class Counter2 {
static int count = 0;// will get memory only once and retain its value
Counter2() {
count++;
System.out.println(count);
}
public static void main(String args[]) {
Counter2 c1 = new Counter2();//1
Counter2 c2 = new Counter2();//2
Counter2 c3 = new Counter2();//3
}
}
静态方法
如果在任何方法上应用static关键字,此方法称为静态方法。
- 静态方法属于类,而不属于类的对象。
- 可以直接调用静态方法,而无需创建类的实例。
静态方法可以访问静态数据成员,并可以更改静态数据成员的值。
//Program of changing the common property of all objects(static field). class Student9 { int rollno; String name; static String college = "ITS"; static void change() { college = "BBDIT"; } Student9(int r, String n) { rollno = r; name = n; } void display() { System.out.println(rollno + " " + name + " " + college); } public static void main(String args[]) { Student9.change(); Student9 s1 = new Student9(111, "Karan"); Student9 s2 = new Student9(222, "Aryan"); Student9 s3 = new Student9(333, "Sonoo"); s1.display();//111 Karan BBDIT s2.display();//222 Aryan BBDIT s3.display();//333 Sonoo BBDIT } }
instanceof
在Java中,可以
Superclass name1 = new Subclass();
,但不能Subclass name1 = new Superclass();
使用java instanceof运算符的向下转换
当子类型引用父类的对象时,它被称为向下转换(downcasting)。 如果直接执行它,编译器会出现编译错误。
集合
Map
遍历 HashMap
import java.util.*;
public class Test{
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");
//第一种:推荐!!,尤其是容量大时
System.out.println("通过Map.entrySet遍历key和value");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
//第二种:普遍使用,二次取值
System.out.println("通过Map.keySet遍历key和value:");
for (String key : map.keySet()) {
System.out.println("key= "+ key + " and value= " + map.get(key));
}
}
value去重
对于HashMap而言,它的key是不能重复的,但是它的value是可以重复的,有的时候我们要将重复的部分剔除掉。
方法一:将HashMap的key-value对调,然后赋值给一个新的HashMap,由于key的不可重复性,此时就将重复值去掉了。最后将新得到的HashMap的key-value再对调一次即可。
ArrayList , LinkedList , Vector
ArrayList和Vector本质都是用数组实现的,而LinkList是用双链表实现的;所以,Arraylist和Vector在查找效率上比较高,增删效率比较低;LinkedList则正好相反。ArrayList是线程不安全的,Vector是线程安全的,效率肯定没有ArrayList高了。实际中一般也不怎么用Vector,可以自己做线程同步,也可以用Collections配合ArrayList实现线程同步。