Java入门
1.选择排序的算法(数组的C R D U可以用集合的方法直接调用)
package test1;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) {
int[] array = {1, 9, 7, 3, 2, 6};
RankNum(array);
System.out.println(Arrays.toString(array));
}
public static boolean RankNum(int[] array) {
if (null == array || 0 == array.length) {
System.out.println("Not Found");
return false;
}
for (int i = 0; i < array.length - 1; i++) {
int num = i;
for (int j = i + 1; j < array.length; j++) {
if (array[num] < array[j]) {
num = j;
}
}
if (num != i) {
int temp = array[num];
array[num] = array[i];
array[i] = temp;
}
}
return true;
}
}
2.构造代码块的使用
初始化成员变量有三种方法:1,定义时初始化;2,构造代码块初始化;3,在构造方法中初始化。
其中构造方法初始化时优先级最高的,剩下的两个谁在后面谁说了算。
构造代码块的好处,不管调用哪个构造方法,都要先经过构造代码块,可以用来初始化当前类的所有类对象,
可以在项目中用来统计计数。
3.用while(true)和switch- case表示
package test1;
public class Demo2 {
public static void main(String[] args) {
boolean flag = fasle;
int choose = 0;
while (true) {
switch (choose) {
case 1:
方法体
break;
case 2:
方法体
break;
case 3:
方法体
flag = true;
break;
default:
break;
}
if(flag) {
break;
}
}
}
}
4.重载和重写
重载:重载是为了满足不同的情况,对方法进行重载,
重载必须保持方法名一样;
重载必须方法的参数类型不一样;
重载必须在同一个类内。
重写:重写是为了希望强制重写,这样写程序可以把运行时错误,提前到编译时错误,很有必要。
重写必须是有继承(extends)(父类)或【遵从】(implements)(接口)关系;
重写要求方法的声明必须一样;
重写要求方法体必须不一样。
(用abstract修饰用来要求进行强制重写)
5.成员变量和局部变量区别
可以从生存周期和作用范围来区别。
6.this关键字
注意事项(4个)
1. 使用this关键字调用其他构造方法,是通过参数的类型不同来选择不同的构造方法。
2. this关键字调用构造方法,有且只能在代码代码块的第一行。
3. 在同一个构造方法,不能出现两个this调用其他构造方法的形式。
4. 两个不同的构造方法,不能通过this关键字相互调用。
5,不能和super关键字混用
7.static关键字
static:共享资源,静态
static修饰的成员变量叫做静态成员变量,放在内存【数据区】;
static修饰的成员方法叫做静态成员方法,放在内存【方法区】。
静态成员变量和静态成员方法与类对象的关系:
因为静态成员变量和静态成员方法是随着.class字节码文件加载到内存时就已经存在于【数据区】或【方法区】,
而类对象是通过new关键字加上对应的构造方法,执行对应语句才被创建到内存【堆区中】,
从生存周期和内存区都可以看出,静态成员变量和静态成员方法根类对象之间“没有关系”!!!!!
调用静态成员变量和静态成员方法,需要用静态的方法调用,即用(类名.变量或方法)直接调用。不能通过类对象调用
8.abstract关键字
使用abstract时注意事项:
1,abstract修饰的成员是没有方法体的,有且只有方法声明(即权限修饰符,返回值类型,参数等);
2,abstract修饰的成员方法必须定义在在abstract修饰的类内。
3,一个类继承abstract修饰的类,则必须实现abstract类内所有的abstract方法。
4,abstract修饰的类能有自己的类对象吗???
答:不能!!!因为abstract修饰的类是有可能存在abstract修饰的方法的,而abstract修饰的方法是没有方法体的,而类对象执行方法是需要方法体的。假如abstract修饰的类有类对象,那么如何调用abstract修饰的方法呢,不能调用abstract方法,所以abstract修饰的类不能有自己的类对象!
5,一个类内没有abstract修饰的方法,那么也可以用abstract修饰这个类,不过纯属多此一举,浪费感情,没有必要。
9.多态的理解
一句话:父类的引用指向子类的对象,接口的引用指向【遵从】接口的类对象。这就是多态。
10.匿名内部类【举例】
package com.qfedu.test;
/**
* 使用abstract修饰的抽象类来演示匿名内部类
* @author Anonymous
*
*/
abstract class A {
abstract public void testA();
}
//一个类继承于抽象类,必须实现在抽象类中的所有抽象方法
class TestA extends A {
//The type TestA must implement the inherited abstract method A.testA()
@Override
public void testA() {
System.out.println("一个类继承抽象类,完成的方法");
}
}
public class TestAbstract {
public static void main(String[] args) {
TestA ta = new TestA();
ta.testA();
//父类的引用指向子类的对象,这叫多态
//A a = new TestA();
//The type new A(){} must implement the inherited abstract method A.testA()
//这类隐含一个继承关系,A类的引用,执行一个继承了A类的子类对象,而该子类是没有名字的
//所以是一个【匿名内部类】。因为类没有名字,所以直接创建对象使用。创建的对象就是abstract
//类A的一个子类对象,而且要求该子类对象,必须完成在abstract类中的所有抽象方法
A a = new A() {
@Override
public void testA() {
System.out.println("abstract类的匿名内部类对象,执行方法");
}
};
//匿名内部类的对象,来调用方法
a.testA();
//TestA类的匿名对象,直接调用成员方法
new TestA().testA();
//匿名内部类的匿名对象直接调用方法 【Android开发】
new A() {
@Override
public void testA() {
System.out.println("匿名内部类的匿名对象,直接调用成员方法");
}
}.testA();
Drinking(ta);
Drinking(new TestA()); //匿名对象作为方法的参数
//匿名内部类的匿名对象,直接作为方法的参数 【非常常用】
Drinking(new A() {
@Override
public void testA() {
System.out.println("匿名内部类的匿名对象,直接作为方法的参数");
}
});
}
/**
*
* @param a
* 这里需要的参数是一个抽象类的子类对象
*/
public static void Drinking(A a) {
a.testA();
}
}
11.集合的概念
Object类是Java中所有类的基类,任何一个类都是直接或者间接继承于Object类;
Collection 接口,Java中所有集合的总接口,不管是哪一个集合实现类对象,都是间接或者直接遵从Collection接口。
Collection 所有集合的总接口
--List<E> 一个子接口,有序,可重复
----ArrayList<E> 一个可变长数组
----LinkedList<E> 链表
----Vector<E> 线程安全的ArrayList,不过效率较低低,一般不用
--Set<E> 一个子接口,无序,不可重复
----HashSet<E> 哈希表
----TreeSet<E> 树形存储
ArrayList<E>(默认数组容量10)的特征:增删慢,查找快。
增加慢:因为增加元素可能会触发ArrayList中的grow方法扩容grow(int minCapacity),而grow方法需要拷贝数据,这个过程非常耗时,另外,在数组中间增加元素时,需要使之后的数组元素整体的右移,这个比较浪费时间。
删除慢:因为可能会删除数组中间的元素,删除后需要之后的数组元素整体的左移,这个比较浪费时间。
查找快:可以按照数组下标方式操作查找,在开发中,数组首地址+元素下标就是在内存的地址,CPU可以直接访问该空间。
LinkedList<e>特征:增删快,查找慢
HashSet<E>存储原理
当一个元素要添加进HashSet集合中是,需要先调用该对象的HashCode值,通过【移位运算】,获取这个元素在哈希表中的位置。(一个add完事,具体不知道);
添加情况1:当前位置没有元素是空的时,可以直接添加进去
情况2:当前位置,存在其他元素时无法直接添加,需要调用当前对象的equals方法进行比较,如果比较结果为同一个元素,无法添加,是不同元素,可以添加。这里需要重写equals方法和HashCode的方法(可以定义元素的特有属性),来进行比较。
TreeSet<E>存储的要求及解决
是一个树形存储,要求添加元素有自然顺序,或者带有比较方式。
有两种方法添加比较方式
①当前需要添加的类,遵从Comparable<T> 实现int compareTo(T o1)
②提供给TreeSet<E>集合一个Comparator<T>接口的实现类对象,实现int compare(T o1, T o2);
12.集合中的方法
Collection方法,
List方法
ArrayList方法
13.String类的方法【重】
28个方法
创建String的方法
String(String str);
String(char[] arr);
String(byte[] arr);
String(char[] arr, int off, int len);
String(byte[] arr, int off, int len);
static String ValueOf(参数类型非常多,放什么返回什么);
获取方法
int length();
int indexOf(String str);
int indexOf(Char ch);
int indexOf(String str, int fromIndex);
int indexOf(char ch, int fromIndex);
int lastIndexOf(Stirng str);
int lastIndexOf(char ch);
String subString(int begin);
String subString(int fromIndex, int toIndex);
String spilt(String str);
char CharAt(int index);
char[] toCharArray();
判断方法:
boolean isEmpty();
boolean endWith(String str);
boolean contains(String str);
boolean equals(String str);
boolean equalsIgnore(String str);
修改方法
String toUpperCase();
String toLowerCase();
String replace(String old, String new);
String replace(char old, char new);
String trim();
14.键值对的概念
//Map <K, V>是键值对;Key是键,不可以重复;value是值,可以重复,我们希望可以通过一个键去找到对应的值
//常用方法
//增加:
put(K key , V value);
putAll(Map<? extends K, ? extends V> map);
//删除:
clear();
remove(Object key);
//修改:
put(K key, V value);
//查询:
int size();
Set<K> keySet();
Collection<V> values();
boolean containsKey(Object key);
boolean containsValue(Object value);
//内部类:
Set<Entry<K, V>> entrySet();
15.反射及详解(以person类为例)
//先来一个Person1类做获取的对象
package text;
public class Person1 {
//成员变量 Field
private Integer id;
private String name;
public int test = 20;
public static int testStatic = 30;
public Person1() {}
public Person1(Integer id) {
super();
this.id = id;
}
public Person1(String name) {
super();
this.name = name;
}
public Person1(Integer id, String name, int test) {
super();
this.id = id;
this.name = name;
this.test = test;
}
private Person1(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private void testPrivate() {
System.out.println("私有化成员方法");
}
public static void testStaticMethod() {
System.out.println("静态成员方法");
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", test=" + test + "]";
}
public void game() {
System.out.println("pubg");
}
public void game(String name) {
System.out.println(this.getName() + "玩"+ name);
}
}
反射的19个方法,获取Person1类
获取.class类对象
package text;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.qfedu.c_reflect.GetConstructorObject;
import com.qfedu.c_reflect.Person;
public class Get {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchFieldException {
//获取Class类对象
//方法一,最常用
Class cla1 = Class.forName("text.Person1");
//方法二,不用
Class cla2 = Person1.class;
//方法三,不用
Class cla3 = new Person1().getClass();
//获取Constructor类对象
//获取所有构造方法,不包括私有化的
Constructor[] constructors = cla1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("神奇的分割符");
//获取所有构造方法,包括私有化的方法
Constructor[] constructors2 = cla1.getDeclaredConstructors();
for (Constructor constructor : constructors2) {
System.out.println(constructor);
}
System.out.println("神奇的分割符");
//获取参数类型为String/null的构造方法,不包括私有化的方法
Constructor constructor3 = cla1.getConstructor(String.class);
Constructor constructor4 = cla1.getConstructor(null);
System.out.println(constructor3);
System.out.println(constructor4);
System.out.println("神奇的分割符");
//获取参数类型为Integer和String的构造方法,包括私有化的方法
Constructor constructor5 = cla1.getDeclaredConstructor(Integer.class, String.class);
System.out.println(constructor5);
System.out.println("神奇的分割符");
//通过参数类型为String的Consturctor类对象,创建一个参数为"狗蛋"的Person类对象
Person1 p = (Person1) cla1.getConstructor(String.class).newInstance("狗蛋");
System.out.println(p);
System.out.println("神奇的分割符");
//给予操作私有化构造方法的权限,为true;
constructor5.setAccessible(true);
Person1 p1 = (Person1) constructor5.newInstance(9,"剩儿");
System.out.println(p1);
System.out.println("分割符");
System.out.println("分割符");
System.out.println("分割符");
//获取Field类对象
//获取所有非私有化Field类对象
Field[] field = cla1.getFields();
System.out.println(field);
System.out.println("神奇的分割符");
//获取所有Field类对象,包括私有化
Field[] field1 = cla1.getDeclaredFields();
System.out.println(field1);
System.out.println("神奇的分割符");
//获取方法名为test的Field类对象,不能是私有化方法
Field field2 = cla1.getField("test");
System.out.println(field2);
//获取方法名为name的Field类对象,包括私有化field类对象
Field field3 = cla1.getDeclaredField("name");
System.out.println(field3);
System.out.println("神奇的分割符")
//给名为p的类对象,赋值field2拥有的数据参数新的值12,不能为私有化Field类对象
field2.set(p, 12);
System.out.println(p.test);
System.out.println("神奇的分割符");
//同上赋值,不过有setAccessible给予权限,可以操作私有化Field类对象
field3.setAccessible(true);
field3.set(p,"过儿");
System.out.println(p.getName());
System.out.println("神奇的分割符");
System.out.println("神奇的分割符");
System.out.println("神奇的分割符");
//获取Method类对象
//获取所有非私有化的成员方法
Method[] methods = cla1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("神奇的分割符");
//获取所有的成员方法,包括私有化的
Method[] methods1 = cla1.getDeclaredMethods();
for (Method method : methods1) {
System.out.println(method);
}
System.out.println("神奇的分割符");
//获取方法名为game,方法的参数类型为String类型的成员方法,不能是私有化成员方法
Method method3 = cla1.getMethod("game", String.class);
System.out.println(method3);
//获取方法名为game,无参数的成员方法,不能是私有化成员方法
Method method4 = cla1.getMethod("game", null);
System.out.println(method4);
//获取方法名为testPrivate,我参数的成员方法,可以是私有化成员方法
Method method5 = cla1.getDeclaredMethod("testPrivate", null);
System.out.println(method5);
//执行此成员方法
//类对象是参数类型为String构造方法通过newInstance将参数"赵子豪"传入创建一个类对象
//方法的实际参数是lol
method3.invoke(cla1.getConstructor(String.class).newInstance("赵子豪"), "lol");
}
}
16.单例的模式
这里是一个简单的单例
public class StaffManager {
//成员变量Field 公司名称
private String companyName;
private static StaffManager st = null;
{
loadData();
}
//构造方法
//无参的构造方法
public StaffManager() {};
//全参的构造方法
public StaffManager(String companyName) {
this.companyName = companyName;
}
public static StaffManager getInstance() {
synchronized (StaffManager.class) {
if (null == st) {
st = new StaffManager();
}
}
return st;
}
public static StaffManager getInstance(String companyName) {
synchronized (StaffManager.class) {
if (null == st) {
st = new StaffManager(companyName);
}
}
return st;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
17, ArrayList数组中中源代码的grow扩容方法
private void grow(int minCapacity) {
//1. 获取原数组容量
int oldCapcity = this.allGoods.length;
//2. 计算新数组容量,大约是原本容量的1.5倍 oldCapcity >> 1 ==> oldCapacity / 2
int newCapacity = oldCapcity + (oldCapcity >> 1);
//3. 确认扩容新数组容量满足最小容量要求
if (minCapacity > newCapacity) {
newCapacity = minCapacity;
}
//4. 新数组容量确认,创建新数组
Goods[] newArray = new Goods[newCapacity];
//5. 拷贝数据
for (int i = 0; i < itemCount; i++) {
newArray[i] = this.allGoods[i];
}
//6. 移行换位!!!
this.allGoods = newArray;
}
19.final关键字
修饰类:不能被继承;
修饰成员方法:不能被子类重写;
修饰成员变量:定义是必须初始化,且不可被修改;
修饰局部变量:赋值后不能被修改
20.接口的缺省属性
接口的成员变量缺省属性:public static final,定义时必须初始化。
接口的成员方法缺省属性,abstract,没有方法体。
21,创建自定义线程的两种方式及哪种方式更好
一个是继承Thread类和一个是遵从Runnable接口类;
第二个更好,
因为Java是门单继承,多接口的语言,如果想实现更多功能,就不能只继承一个类,而多接口保证了代码的延展性。
22. 泛型有什么作用?泛型在接口中使用有几种方式?
泛型作用:
数据的约束,数据类型一致化
运行时错误/ 异常,前置到编译时
避免在程序运行过程中,没有必要的强制类型转换
格式:ArrayList< String> list = new ArrayList < String> ( ) ;
class A < T> implements B < T> {
在A类遵从B接口时没有约束A的数据类型,可以创建自己类对象时再进行约束数据类型,比较自由
}
2.
class C implements B < String> {
C类遵从B接口时数据类型就已经进行约束,C的数据类型必须也是String,
}