问题30:
问题29:
aa
cc:
aasdf
问题28:
问题27:
问题26:
问题25:
问题24:
问题23:
问题22:
问题21:
问题20:
问题19:
问题18:
问题17:
多线程的同步:
- 同步锁对象
package hello;
public class TicketThread implements Runnable{
int tickets = 50;
Object mutex = new Object();
@Override
public void run() {
while(true) {
synchronized (mutex) {
if(tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + tickets--);
}
}
}
}
}
- 非静态同步方法(非静态同步方法的锁对象是this)
package hello;
public class TicketThread implements Runnable{
int tickets = 50;
Object mutex = new Object();
@Override
public void run() {
while(true) {
method();
}
}
protected synchronized void method() {
if(tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + tickets--);
}
}
}
- 静态同步方法(静态同步方法的锁对象是当前类的字节码对象)
问题16:
多线程的两种实现方式:
- extended Thread
- implements Runnable
问题15:
编码表:
ASCII 基本码表
GBK 中国字符码表
Unicode 所有字符都占2个字节
UTF-8 长度可变码表
ANSI 本地编码表,根据系统环境语言变化。
问题14:
Properties和IO流结合功能:
Properties是Hashtable的子类,属于持久属性集。
void list(PrintWriter out)可以直接将集合输出。
void load(Reader reader)
问题14:
输入输出流:
标准输入输出流:
输入 System.in
输出 System.out
字节流:
输入 InputStream FileInputStream
输出 OutputStream FileOutputStream
字符流:(字符流= 字节流+编码)
输入 Reader FileReader
输出 Writer FileWriter
字节流与字符流之间的桥梁:
InputStreamReader #是字节流通向字符流的桥梁
OutputStreamWriter #是字符流通向字节流的桥梁
高效缓冲字节流:
BufferedInputStream
BufferedOutputStream
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
BufferedReader br = new BufferedReader(new FileReader("a.txt"))
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"))
高效缓冲字符流:
BufferedReader
BufferedWriter
打印流:
PrintStream()
PrintWriter() #自动将字节输出流转换为字符输入流。 类似:new BufferedWriter(new FileWriter("a.txt"))
特点:自动换行(print,println,format)、自动刷新(print,println,format)
对象操作流:
ObjectOutputStream(OutputStream out)
ObjectInputStream(InputStream in)
注意:对象操作流的对象一定要实现序列化接口Serializable。解决对实现序列化接口出现的黄色警告问题,需要手动
给类添加序列号serialVersionUID。
问题13:
Map对象的两种遍历方式
方式一: 先获取keyset,然后遍历。
Map<String, String> map = new HashMap<String, String>();
System.out.println(map.put("wy001", "czh"));
System.out.println(map.put("wy002", "ouyy"));
System.out.println(map.put("wy003", "xcz"));
System.out.println(map);
Set<String> keys = map.keySet();
for (String key : keys) {
String value = map.get(key);
System.out.println(value);
}
方式二:获取map.entry,然后遍历。
Map<String, String> map = new HashMap<String, String>();
System.out.println(map.put("wy001", "czh"));
System.out.println(map.put("wy002", "ouyy"));
System.out.println(map.put("wy003", "xcz"));
System.out.println(map);
Set<Map.Entry<String, String>> entrys = map.entrySet();
for(Map.Entry<String, String> entry : entrys) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "+" + value);
}
问题12:
集合的三种遍历方式:
- toArray() ---- 转换为数组遍历
- Iterator ---- 采用迭代器对象
- for(obj st : c) ---- 增强for
备注:对于List集合还可以用普通for循环来遍历,因为有index。
问题11:
迭代器并发修改错误:
使用迭代器迭代集合的同时需要修改集合元素:
错误方式:
package hello;
import java.awt.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;
public class IteratorDemo {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
Iterator it = c.iterator();
while(it.hasNext()) {
String s = (String) it.next();
if(s.equals("java")) {
c.add("android");
}
}
System.out.println(c);
}
}
迭代器是原来集合的一个副本,当迭代器操作的时候,发现和集合不一样,会报并发修改异常。
正确方式:
import java.awt.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;
public class IteratorDemo {
public static void main(String[] args) {
ArrayList c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
ListIterator it = c.listIterator();
while(it.hasNext()) {
String s = (String) it.next();
if(s.equals("java")) {
it.add("android");
}
}
System.out.println(c);
}
}
用迭代器来修改集合,迭代完成后,会同步到原集合。
问题10:
基本数据类型和相对应的包装类
基本数据类型 | 相对应的包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolen | Boolen |
问题9:
修饰符总结:
修饰符 | 类 | 成员变量 | 成员方法 | 构造方法 |
---|---|---|---|---|
public | Y | Y | Y | Y |
default | Y | Y | Y | Y |
protected | N | Y | Y | Y |
private | N | Y | Y | Y |
abstract | Y | N | Y | N |
static | N | Y | Y | N |
final | Y | Y | Y | N |
备注:Y代表可以修饰,N代表不能修饰。成员内部类不在此次考虑范围内。static 可以修饰成员内部类。
问题8:
权限修饰符的方法的作用域:
- public : 当前类、相同包下不同类、不同包下的类
- default : 当前类、相同包下不同类
- protected: 当前类、相同包下不同类
- private:当前类
另外:default是用于包内,protected可以用于子类。
问题7:
多态成员特点:
- 成员变量:成员变量是没有重写的,所以编译时看左边,运行时看左边。
- 成员方法:编译时看左边,运行时看右边。
- 静态方法:编译时看左边,运行时看左边。
package hello;
public class PoymorphicDemo {
public static void main(String[] args) {
Animal a = new Cat();
System.out.println(a.num);//20
a.eat();//cat eat fish...
a.foo();//我是父类静态方法
}
}
class Animal{
int num = 20;
public void eat() {
System.out.println("eating ...");
}
public static void foo() {
System.out.println("我是父类静态方法");
}
}
class Cat extends Animal{
int num = 10;
public void eat() {
System.out.println("cat eat fish");
}
public static void foo() {
System.out.println("我是子类静态方法");
}
}
问题6:
final修饰类、成员方法、成员变量
- final修饰类:不能被继承、不能有子类。
- final修饰的成员方法:不能被重写。
- final修饰的成员变量:不可以被修改,一旦初始化就不可以改变。
- 可以显示初始化:final int a = 1;
- 可以构造初始化: 在构造函数中进行初始化。
问题5:
抽象类与接口的区别:
抽象类 | 接口 |
---|---|
单继承 | 多实现 |
有抽象方法也有非抽象方法 | 只能有抽象方法 |
有成员变量也可以有成员常量 | 只能有成员常量 |
有构造方法 | 无构造方法 |
问题4:
List接口和Set接口的区别:
List 接口实现的类中元素是有序可重复的。
Set 接口实现的类中元素是无序不重复的。
问题3:
接口与类之间的关系
- 类与类之间的关系:继承 extends, 单一继承,多层继承
- 类与接口之间的关系:实现 implements, 多继承,多实现
- 接口与接口之间的关系:继承 extends
问题2
String类型的比较,看如下代码和相应的结果:
String s1 = new String("hello");
String s2 = "hello";
String s3 = "hello";
System.out.println(s1==s2);//false
System.out.println(s1==s3);//false
System.out.println(s2==s3);//true
为什么最后一个比较的结果为true?
为了字符串的重复使用,字符串常量的内容是存储在方法区的常量池里面的。如下图所示:
问题1:
String为引用类型,当String变量作为函数参数传递时,即使函数内部修改了String的值,为什么不影响原来的值(函数外面的该参数),为什么和传递数组名不一样?
JAVA数据类型有两种:基本类型和引用类型
- 基本类型:byte short int long float double char boolen
- 引用类型:类、接口、数组
原因:String是一个final修饰的类,JAVA虚拟机在每次修改String的值时都是重新申请内存。因此不会影响方法外该变量的值。如果用StringBuilder就不一样了,用append拼接字符串后,是在原有地址上扩充。