Java Summary:

JRE(java runtime emvuronment):

包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,
如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可

JDK(Java Development Kit    Java开发工具包):
JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE。所以安装了JDK,就不用在单独安装JRE了。
其中的开发工具:编译工具(javac.exe)  打包工具(jar.exe)等

简单来说就是用jdk开发出完成额java程序,交给jre运行

一些要注意的问题:
java严格区分大小写:
关键字一般都是小写
class文件的文件名为单词首字母大写
public的访问权限最高
static 可以定义一个静态的变量

常见的命名规则(见名知意)
A:包 全部小写
单级包:小写
举例:liuyi,com
多级包:小写,并用.隔开
举例:cn.itcast,com.baidu
B:类或者接口
一个单词:首字母大写
举例:Student,Demo
多个单词:每个单词首字母大写
举例:HelloWorld,StudentName
C:方法或者变量
一个单词:首字母小写
举例:name,main
多个单词:从第二个单词开始,每个单词首字母大写
举例:studentAge,showAllNames()
D:常量
全部大写
一个单词:大写
举例:PI
多个单词:大写,并用_隔开
举例:STUDENT_MAX_AGE

数据类型转换(掌握)
(1)boolean类型不参与转换
(2)默认转换
A:从小到大
B:byte,short,char -- int -- long -- float -- double
C:byte,short,char之间不相互转换,直接转成int类型参与运算。
System.out.println('a'+1);这就说明这个输出的将会是个值
(3)强制转换
A:从大到小
B:可能会有精度的损失,一般不建议这样使用。
C:格式:
目标数据类型 变量名 = (目标数据类型) (被转换的数据);

注意"hello"+1+2+'a'  -->hello12a 字符串的拼接
1+2+'a'+"hello" -->68hello

数据类型:
一般分为基本数据类型和引用数据类型
基本数据类型:常用的4类8种
A:整数 占用字节数
byte 1
short 2
int 4
long 8
B:浮点数
float 4
double 8
C:字符
char 2
D:布尔
boolean 1

注意:
整数默认是int类型,浮点数默认是double。

长整数要加L或者l。
单精度的浮点数要加F或者f。
引用数据类型:类,接口和数组

请用最有效率的方式写出计算2乘以8的结果
10<<3 左移动3位

switch(“ ”)里面的可以是常量,boolean,string--1.7以后的 ,enum等

面向对象:(封装:private 继承:extends  多态 :父类->转向子类FU fu = new ZI();   或者强制转换ZI zi =new  (ZI)fu 接口-->子类的具体实现类interface inter = new ZI()  )
面向对象: 属性 和 行为
属性:名称  用来描述的东西
行为: 本来具有的功能
接口: 本来不会的 但拓展出来的

多态的弊端:
不能使用子类的功能。
解决办法:
Fu f  = new Zi();

Zi z = (Zi)f;
这样的好处在于节省内存
*/

class Fu{
public void show(){
System.out.println("this is Fu");
}
public Fu(String name){
System.out.println("haha");
}
}
class Zi extends Fu{
public Zi(){
super("haha");
}
public void method (){
System.out.println("this is Zi");
}
}

class ZhuanXing{
public static void main(String[] args){
Fu f  = new Zi();//子类向上转型
f.show();
//f.method();
Zi z = (Zi)f;//将子类强制付给父类,省内存空间,父类向下转型
z.method();
}
}

/*下面使一些选择排序和冒泡排序*/

public static void sortarray(int array[]){
/*for(int x=0;x<array.length;x++){
for(int y=x+1;y<array.length;y++){
if(array[x]>=array[y]){
int temp ;
temp=array[x];
array[x]=array[y];
array[y]=temp;
}
}
} 这种叫选择排序*/
for(int x=0;x<array.length-1;x++){
for(int y=0;y<array.length-1-x;y++){
if(array[y]>=array[y+1]){
int temp ;
temp=array[y];
array[y]=array[y+1];
array[y+1]=temp;
}
}
}
/*这种叫冒泡*/

静态变量:可以通过对象名调用,也可以通过类名调用
成员变量:只能通过对象名调用
方法也是一样的

class Student {
static {
System.out.println("静态代码块");

}
{
System.out.println("构造代码块");
}
public Student(){
System.out.println("构造方法");
}
}

执行顺序:
起始的main方法--静态代码块 -- 构造代码块 -- 构造方法
静态代码块:只执行一次
构造代码块:每次调用构造方法都执行

this: this.name = name 中this代表的是指向调用方法的对象
private name 使变量不与外界有任何联系,可以通过在类中新建一个方法来进行赋值运算

匿名对象:
好处:一旦一次调用完就是垃圾,立即回收;
new Student()为一个匿名的对象

匿名的内部类:
一般是这么使用:
interface Inter{
void show();
}

class Outer{
public static Inter method(){
return new Inter(){
public void show(){
System.out.println("HelloWorld");
}
};
}
}

class OuterDemo{

public static void main(String[] args){
Outer.method().show();
}
}

创建一个接口inter 然而我们即是inter i = new inter(){
//重写inter里的方法
void show(){
System.out.println("这是匿名内部类");

}
};作为一个子类实现类的对象来用   这种也成为多态

抽象类:
抽象类里面可以有各种方法,包括一般的成员方法,抽象方法等
如果一个类中有抽象方法,那么其类一定为抽象类或者接口
抽象的东西一般通过子类继承实现对抽象方法的重写顾纵着匿名内部类等来实现调用

public abstract Abstr(){
public abstract eat();
public void show(){}

}

java的类是单继承的,不可以多继承,但可以多重继承
不可写成这样:
 A extends B,C
 
 但可以
B extends C
A extends B

这样就继承了两个类

子类与父类:
子类不能继承父类的私有成员变量,也不可以访问私有化的方法

子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法

this(...)或者super(...)必须出现在第一条语句上。
如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。

那么如何在一个类中调用另一个类的私有方法或者变量呢?
解决前提是:不继承
然后用反射的方式调用
例如下面的例子:
public class A {
public static void main(String[] args) throws Exception, Exception {
Class<B> c = B.class;//获取.class文件

Constructor<B> con = c.getDeclaredConstructor();//调用构造方法

B b =con.newInstance();//创建实例对象

//调用私有方法
Method m = c.getDeclaredMethod("show");//私有方法的名字
m.setAccessible(true);

m.invoke(b);//用所创建的对象b调用方法m

}
}

public class B {
private void show(){
System.out.println("hellow this world");
}
private int age;
public B(){};

}

输出结果:hellow this world

接口:
public interface inter(){
public abstract void show();

}

你可能看到一些正则表达式:放在Pattern这个类下

String str = " a wo lai zi jie yang ";
String regex = "\\b\\w{2}\\b"; 
//这里表示出现两个\w 单词字符:[a-zA-Z_0-9] 即是wo zi \\b代表单词边界
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
//-->Matcher m = Patter.compile(regex).matcher(str)
//输出结果
while(m.find()){
System.out.println(m.group());
}

下面为一个例子匹配手机号码是否正确:
public class Regex {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个手机号码:");
String str = sc.nextLine();
System.out.println("是否正确?"+'\n'+check(str));
boolean b = Pattern.matches("[1-9]{5}", "12345");
System.out.println(b);
}
//public boolean matches(String regex)
public static boolean check(String str ){
boolean flag = str.matches("1[3456798][0-9]{9}");
return flag;

}

集合和数组:
区别:
数组:可以存储基本类型或引用类型,但只能存储一种类型,如存储5个学生对象等,数组的长度固定
集合:可以存储多种类型,而且这类型只能是引用类型,不过在加了泛型之后也就相当于存储一种类型
而集合的长度可变
集合:     Collection 
List Set

ArrayList Vector Linkedlist Hashset     Treeset    LinkedHashSet

ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
HashSet
底层数据结构是哈希表。
如何保证元素唯一性的呢?
依赖两个方法:hashCode()和equals()
开发中自动生成这两个方法即可

LinkedHashSet
底层数据结构是链表和哈希表
由链表保证元素有序
由哈希表保证元素唯一
TreeSet
底层数据结构是红黑树。
如何保证元素排序的呢?
自然排序 
比较器排序
如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定
在集合中常见的数据结构(掌握)
ArrayXxx:底层数据结构是数组,查询快,增删慢
LinkedXxx:底层数据结构是链表,查询慢,增删快
HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序

针对Collection集合我们到底使用谁呢?(掌握)
唯一吗?
是:Set
排序吗?
是:TreeSet
否:HashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。

否:List
要安全吗?
是:Vector
否:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。

如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。

如果你知道用集合,就用ArrayList。

Map和Collection的Set相似,区别是加了键 ,所以是成对存在的
Map: HashMap  TreeHap
Map<String,String> hm = new HashMap<String,String>();

可以按CRTL SHIFT F来使整个格式好看

ctrl /  可以快速注释
ctrl shift / 快速注释/* */
ctrl shift \ 打开注释

//通过键盘获取一个对象,封装对象,用反射
public static Object getObject(Object object) throws ClassNotFoundException, Exception, SecurityException{
Scanner sc = new Scanner(System.in);

Class cls = Class.forName(object.getClass().getName());

Constructor<Object> construct = cls.getDeclaredConstructor();

object = construct.newInstance();

Field[] fields = cls.getDeclaredFields();

for(Field f: fields){
System.out.println("请输入该对象的名称"+f.getName()+"字段的类型为"+f.getType());

f.setAccessible(true);
//f.set(object, sc.next());
//System.out.println(f.getType());
//System.out.println(f.getType().getName());
if(f.getType().getName().equals("java.lang.String")){

f.set(object, sc.next());
}
else{

f.set(object,sc.nextInt());
}
}

return object;
}

public class CountDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);

System.out.println("请输入一个字符串:");

String chs = sc.nextLine();

char cha[] = chs.toCharArray();
for(char s:cha){
System.out.print("["+s+"]");
}

TreeMap<Character,Integer> ch = new TreeMap<Character,Integer>();
//

for(Character s:cha){
Integer i = ch.get(s);
System.out.println(i);
if(i==null){
ch.put(s, 1);
}
else {
i++;
ch.put(s, i);

}

}
//键找值
Set<Character> set = ch.keySet();//返回的是提个set集合
StringBuilder  sb = new StringBuilder();
for(Character c:set){//键找值
sb.append(c).append("(").append(ch.get(c)).append(")");
}
System.out.println();
System.out.println(sb);

//通过键值对找键和值
Set<Map.Entry<Character, Integer>> set2 = ch.entrySet();
for(Map.Entry<Character, Integer> m:set2){
Character key = m.getKey();
Integer value = m.getValue();
System.out.print(new StringBuffer().append(key).append("(").append(m.getValue()).append(")"));

}

}
}

模仿斗地主:
/*
 * 模仿斗地主
 * A:创建一个HashMap集合
 * B:创建一个ArrayList集合
 * C:创建花色数组和点数数组
 * D:从0开始往HashMap里面存储编号,并存储对应的牌
 *        同时往ArrayList里面存储编号即可。
 *      E:洗牌(洗的是编号)Collections.
 *      F:发牌(发的也是编号,为了保证编号是排序的,就创建TreeSet集合接收)
 *      G:看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)*/
public class FightDemo {
public static void main(String[] args) {
HashMap<Integer,String> hash = new HashMap<Integer,String>();

ArrayList<Integer> list = new ArrayList<Integer>();

String[] color1 = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
String[] color2 ={"黑","红","梅","方"};

int index = 0;
for(String c1:color1){
for(String c2:color2){
String c3=c2.concat(c1);
list.add(index++);
System.out.println(c3);
hash.put(index, c3);

}
System.out.println();
}
System.out.println(list);

list.add(index);
hash.put(index, "小王");
hash.put(index,"小王" );
index++;
hash.put(index, "大王");
list.add(index);
hash.put(index,"大王" );

//这里主要是因为list<Integer> list ==index;

//System.out.println(list);
/*for (int x = 0; x < array.size(); x++) {
if (x >= array.size() - 3) {
diPai.add(array.get(x));
} else if (x % 3 == 0) {
fengQingYang.add(array.get(x));
} else if (x % 3 == 1) {
linQingXia.add(array.get(x));
} else if (x % 3 == 2) {
liuYi.add(array.get(x));
}
}*/

Collections.shuffle(list);//洗牌

//底牌和三个人
TreeSet<Integer> p1 = new TreeSet<Integer>();
TreeSet<Integer> p2 = new TreeSet<Integer>();
TreeSet<Integer> p3 = new TreeSet<Integer>();
TreeSet<Integer> dipai = new TreeSet<Integer>();
//发牌
for(int x=0;x<list.size();x++){
if(x>=list.size()-3){
dipai.add(list.get(x));
}else if(x%3==0){
p1.add(list.get(x));
}else if(x%3==1){
p2.add(list.get(x));
}else if(x%3==2){
p3.add(list.get(x));
}
}

//遍历看牌
/*public static void lookPoker(String name, TreeSet<Integer> ts,
HashMap<Integer, String> hm) {
System.out.print(name + "的牌是:");
for (Integer key : ts) {
String value = hm.get(key);
System.out.print(value + " ");
}
System.out.println();
}*/
look("dipai",dipai,hash);
look("sb1",p1,hash);
look("sb2",p2,hash);
look("sb3",p3,hash);

}
//遍历看牌
public static void look(String name, TreeSet<Integer> ts,
HashMap<Integer, String> hm) {
System.out.print(name + "的牌是:");
for (Integer list: ts) {
String value = hm.get(list);
System.out.print(value + " ");
}
System.out.println();
}

}

三层嵌套:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

/*三层嵌套*/
public class HashMapDemo3 {
public static void main(String[] args) {
HashMap<String,HashMap<String,ArrayList<Student>>> hash = new HashMap<String,HashMap<String,ArrayList<Student>>>();

//江北校区---就业班--的学生
Student s1 = new Student("jobis",27);
Student s2 = new Student("bios",20);

ArrayList<Student> array1 = new ArrayList<Student>();
array1.add(s1);
array1.add(s2);
HashMap<String,ArrayList<Student>> h1 = new HashMap<String,ArrayList<Student>>();
h1.put("就业班", array1);

hash.put("江北校区", h1);

//江南校区--基础班--学生

Student s3 = new Student("hellow",28);
Student s4 = new Student("jaava",29);
ArrayList<Student> array2 = new ArrayList<Student>();
array2.add(s3);
array2.add(s4);
HashMap<String,ArrayList<Student>> h2 = new HashMap<String,ArrayList<Student>>();
h2.put("基础班", array2);

hash.put("江南校区", h2);

Set<String> set = hash.keySet();//Set<对应的类型就是HashMap<String,HashMap<String,ArrayList<Student>>的第一个键的类型> >

//所谓的遍历就是要从外到内把每一层的键所获得的值作为下一个的键
for(String st1:set){
System.out.println(st1);
//HashMap<String,ArrayList<Student>>;
HashMap<String, ArrayList<Student>> st1Value = hash.get(st1);
//再将第一个的键的所获得的建的值作为第二个键而且是HashMap类型
Set<String> set2 = st1Value.keySet();//在这里就用到了HashMap类型
for(String st2:set2){
System.out.println("\t"+st2);
ArrayList<Student> array = st1Value.get(st2);
for(Student std : array){
System.out.println("\t\t"+std.getName()+"----"+std.getAge());
}
}
/*
* 江南校区
基础班
hellow----28
jaava----29
江北校区
就业班
jobis----27
bios----20

HashMap<String,HashMap<String,ArrayList<Student>>> 
*/

TreeMap<Person,String> p = new TreeMap<Person,String>(new Comparator<Person>(){

@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
int num = o1.getAge()-o2.getAge();
int num1 = num==0?o1.getName().compareTo(o2.getName()):num;
return num1;
}

});//匿名内部类改写该Comparator的的方法

1.8之后的接口里面可以有默认的方法

如:public interface Comparator<T> {
int compare(T o1, T o2);//1.7之前的
 
 default Comparator<T> thenComparing(Comparator<? super T> other) {
        Objects.requireNonNull(other);
        return (Comparator<T> & Serializable) (c1, c2) -> {
            int res = compare(c1, c2);
            return (res != 0) ? res : other.compare(c1, c2);
        };
    }//1.8之后的
    
}

public class HashMapDemo {
public static void main(String[] args) {
HashMap<String,ArrayList<String>>  hash = new HashMap<String,ArrayList<String>>();

ArrayList<String> array1 = new ArrayList<String>();
array1.add("周瑜");
array1.add("诸葛亮");

hash.put("三国", array1);

ArrayList<String> array2 = new ArrayList<String>();
array2.add("武大");
array2.add("宋江");

hash.put("水浒传", array2);

ArrayList<String> array3= new ArrayList<String>();
array3.add("达成");
array3.add("狗日");

hash.put("阿西吧", array3);

Set<String> set = hash.keySet();
for(String key1:set){
System.out.println(key1);
ArrayList<String> s = hash.get(key1);//再把前面的通过键获取的值作为第二个的键,然后通过该键获取值
for(String value2: s){
System.out.println("\t"+value2);
}

}

}
}

文件IO Stream:

字节流
InputStream 
OutputStream

读取写入文件的四种方法:注意对于普通的字符形式的文件可以采用字符流或者字节流,但对于视频等其他文件采用字节流

高效的字节流为BufferedInputStream 和 BufferedOutputStream

BufferedOutputStream buffered = new BufferedOutputStream(new FileOutputStream("E:\\IO\\最后的巫师猎人.rmvb"));

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class StandardIO {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
//method1();//410021毫秒
//method2();//842毫秒
//method3();//3974毫秒
method4();//190毫秒
long end = System.currentTimeMillis();
System.out.println("消耗的时间为:"+(end-start)+"毫秒");
}

public static void method1() throws IOException{

FileInputStream s = new FileInputStream("E:\\IO\\01 周杰伦专辑《Jay》.zip");

FileOutputStream cs = new FileOutputStream("Mrzhou.zip");
int d=0;
while((d=s.read())!=-1){
cs.write(d);
}
s.close();
cs.close();

}

public static void method2() throws IOException{

FileInputStream s = new FileInputStream("E:\\IO\\01 周杰伦专辑《Jay》.zip");

FileOutputStream cs = new FileOutputStream("Mrzhou1.zip");

byte[] a =new byte[1024];
int d = 0;
while((d=s.read(a))!=-1){
cs.write(a);
}
s.close();
cs.close();
}

public static void method3() throws IOException{
/*public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。 */
BufferedInputStream s = new BufferedInputStream(new FileInputStream("E:\\IO\\01 周杰伦专辑《Jay》.zip"));

BufferedOutputStream cs = new BufferedOutputStream(new FileOutputStream("Mrzhou2.zip"));

int d=0;
while((d=s.read())!=-1){
cs.write(d);
}
s.close();
cs.close();
}

public static void method4() throws IOException{

BufferedInputStream s = new BufferedInputStream(new FileInputStream("E:\\IO\\01 周杰伦专辑《Jay》.zip"));

BufferedOutputStream cs = new BufferedOutputStream(new FileOutputStream("Mrzhou3.zip"));

byte[] a = new byte[1024];
int d=0;
while((d=s.read(a))!=-1){
cs.write(a);
}
s.close();
cs.close();

}

递归查找:

/*递归实现查找.java后缀的文字*/
public class DiGUi {
public static void main(String[] args) {
File f = new File("E:\\javaSE");

lookforward(f);

}
//递归实现
public static void  lookforward(File source){
File[] array = source.listFiles();
for(File s:array){
//需要先遍历一下File
if(s.isDirectory()){
lookforward(s);
}else{
if(s.getName().endsWith(".java")){
System.out.println(s.getAbsolutePath());
}
}
}
}
}

创建键盘输入流:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.read();

IO流小结:
IO流
|--字节流
|--字节输入流
InputStream
int read():一次读取一个字节
int read(byte[] bys):一次读取一个字节数组

|--FileInputStream
|--BufferedInputStream
|--字节输出流
OutputStream
void write(int by):一次写一个字节
void write(byte[] bys,int index,int len):一次写一个字节数组的一部分

|--FileOutputStream
|--BufferedOutputStream
|--字符流
|--字符输入流
Reader
int read():一次读取一个字符
int read(char[] chs):一次读取一个字符数组

|--InputStreamReader
|--FileReader
|--BufferedReader
String readLine():一次读取一个字符串
|--字符输出流
Writer
void write(int ch):一次写一个字符
void write(char[] chs,int index,int len):一次写一个字符数组的一部分

|--OutputStreamWriter
|--FileWriter
|--BufferedWriter
void newLine():写一个换行符

void write(String line):一次写一个字符串

字符流
(1)字节流操作中文数据不是特别的方便,所以就出现了转换流。
  转换流的作用就是把字节流转换字符流来使用。
(2)转换流其实是一个字符流
字符流 = 字节流 + 编码表
(3)编码表
A:就是由字符和对应的数值组成的一张表
B:常见的编码表
ASCII
ISO-8859-1
GB2312
GBK
GB18030
UTF-8
C:字符串中的编码问题
编码
String -- byte[]
解码
byte[] -- String
(4)IO流中的编码问题
A:OutputStreamWriter
OutputStreamWriter(OutputStream os):默认编码,GBK
OutputStreamWriter(OutputStream os,String charsetName):指定编码。
B:InputStreamReader
InputStreamReader(InputStream is):默认编码,GBK
InputStreamReader(InputStream is,String charsetName):指定编码
C:编码问题其实很简单
编码只要一致即可

还有一个打印流针流(高效,方便)
(1)字节打印流,字符打印流
(2)特点:
A:只操作目的地,不操作数据源
B:可以操作任意类型的数据
C:如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新
D:可以直接操作文件
问题:哪些流可以直接操作文件呢?
看API,如果其构造方法能够同时接收File和String类型的参数,一般都是可以直接操作文件的
(3)复制文本文件
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);

String line = null;
while((line=br.readLine())!=null) {
pw.println(line);
}

pw.close();
br.close();

Properties(配置文件)
(1)是一个集合类,Hashtable的子类
(2)特有功能
A:public Object setProperty(String key,String value)
B:public String getProperty(String key)
C:public Set<String> stringPropertyNames()

线程Thread:
class Thread implements Runable{}
Thread 是一个类,并且实现了Runnable接口,而Runnable接口就只有一个抽象方法:
public interface Runnable {
public abstract void run();
}
而class Thread implements Runnable {
   private Runnable target;
   
    @Override
   public void run() {
       if (target != null) {
           target.run();
       }
   }
}
里面并没有对run()方法进行最基本的重写;所以在用Thread里面的run()方法的时候
很有必要对其进行重写来实现我们的目的
由于Thread还有关于将Runnable作为参数的有参构造方法
所以进行进程的时候有两种方式:
一是用子类继承Thread
二是用子类实现Runable接口,并用Thread将子类对象加载进来,因为很多方法都在
Thread类里面

守护线程的理解:
s1.setName("守护线程");
s2.setName("java");

s1.setDaemon(true);
s1.start();
//s2.start();
当把s2.start()注释掉的时候,这时s1也会随着结束
s1守护着s2,随着s2的结束而结束

线程锁的理解:
public class MyRunnable implements Runnable {

private int ticket =100;//共享的数据都要为全局变量

private Object d = new Object();//方法锁的对象可以是任意的,同一把锁就要求定义为全局变量

/*public void run() {
// TODO Auto-generated method stub
while(true){

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//延迟,让所有的进程进来
synchronized (d) {
if(ticket>0){
System.out.println(Thread.currentThread().getName()+"正在售出第"+(ticket--)+"票");
}
}//把需要锁的代码全部锁起,也是创建同步进程!

}
}*/

public void run() {
// TODO Auto-generated method stub
while(true){

try {
Thread.sleep(1000);//延迟,让所有的线程进来,这一步不能省
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*synchronized (d) {
if(ticket>0){
System.out.println(Thread.currentThread().getName()+"正在售出第"+(ticket--)+"票");
}
}//把需要锁的代码全部锁起,也是创建同步线程!*/
synchronized(this){
manage();
}

}
}

private synchronized void manage(){

if(ticket>0){
System.out.println(Thread.currentThread().getName()+"正在售出第"+(ticket--)+"票");
}

}

}

test:
/*电影售票问题:
共100张票
三个窗口:*/
public class FilmDemo {
public static void main(String[] args) {
MyRunnable my = new MyRunnable();

Thread t1 = new Thread(my,"窗口1");
Thread t2 = new Thread(my,"窗口2");
Thread t3 = new Thread(my,"窗口3");

t1.start();
t2.start();
t3.start();

}
}

三个线程:
首先其执行具有无序性,在Thread.sleep(1000)中先让三个进程进来,在锁对象的时候即就是synchronized(普通的方法的用this,全局变量对象用该对象),锁起来
然后等待一个线程执行完了之后再进行上一个线程,由于while的循环,会源源不断地将线程传进来
而本线程有个缺点就是没有关闭线程

线程安全day24-src-com.xiancheng or com.xiancehng2

线程间的通信:两个包
java.net.DatagramSocket:This class represents a socket for sending and receiving datagram packets
java.net.DatagramPacket:This class represents a datagram packet.

两种协议:
UDP:数据打包,有限制,不连接,效率高,不可靠
TCP:建立数据通道,无限制,效率低,可靠

UDP流程:
   (1)接收:
    创建UDP接收端的Socket对象      DatagramSocket 
创建数据包用于接收数据
接收数据
解析数据包
释放资源
(2)发送:
创建UDP发送端的Socket对象
创建数据并把数据打包
发送数据
释放资源
TCP流程:
(1)接收:
创建TCP服务器端的Socket对象
监听客户端连接
获取输入流,读取数据
释放资源
(2)发送:
创建TCP客户端的Socket对象
获取输出流,写数据
释放资源

可以创建两个线程来通信,然后在main方法里面启动两个线程

也可以创建两个main方法,不过在运行的时候需要自己注意一下运行顺序,先服务器端,再用户端
or 先接收端,再发送端

一般常用的聊天工具具备两种协议:
TCP:适合发送和接收文件或者大文件等
UDP:适合聊天信息的发送,手机短信等

服务器和客户端之间

客户端:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

/*服务器端*/
public class Sever {
public static void main(String[] args) throws IOException {
//创建服务器对象
ServerSocket ss = new ServerSocket(10086);

//创建接收Socket对象
Socket s = ss.accept();

//创建通道读入流
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

//创建存储文件流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("rec.java")));

//开始读入并写入数据
String line =null;
while((line =br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}

//写入反馈
//将服务器端的输出流作为客户端的读入流
BufferedWriter serverwriter = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
serverwriter.write("文件上传成功");
serverwriter.newLine();
serverwriter.flush();

s.close();
bw.close();
br.close();
serverwriter.close();

}
}

客户端:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/*假设从客户端发送数据到服务器,客户端和服务器分别作出反馈
 * 文本文件:
 * 图片文件
 * 视频文件
 * 那么反馈要写在哪里?:
 * 写在文件写入结束的地方
 * */
public class Client {
public static void main(String[] args) throws IOException, IOException {
//创建Socket对象
Socket s = new Socket("zhengbaozhong",10086);

//创建发送文件的读入流
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ReciveDemo2.java")));
//创建通道写入流对象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

String line =null;
while((line=br.readLine())!=null){    //通道读入流跑到这里被阻了
bw.write(line);
bw.newLine();
bw.flush();
}
//为什么s.shutdownOutput();会在这里?
s.shutdownOutput();
//读入反馈
BufferedReader cilentread = new  BufferedReader(new InputStreamReader(s.getInputStream()));
String str =cilentread.readLine();
System.out.println(str);

//释放资源
bw.close();
s.close();
br.close();
cilentread.close();

}
}

总结:服务器端和客户端多了一个通道流
服务器的通道输出流将作为客户端的通道读入流
在这个过程会产生阻塞现象,所以必须在读入流下加入new Socket().shutdownOutput();
而服务器端一般不关闭

UDP:

接收端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReciveThread implements Runnable{
private DatagramSocket ds;

public ReciveThread(){}
public ReciveThread(DatagramSocket ds){
this.ds = ds;
}
public void run() {
// TODO Auto-generated method stub
//创建接收的数据包
while(true){
byte[] byt = new byte[1024];
int leng = byt.length;

DatagramPacket dp = new DatagramPacket(byt,leng);
//获取数据包
try {
ds.receive(dp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//获取dp的Ip:
String ip = dp.getAddress().getHostAddress();
//解析数据包
//byte[] by = dp.getData();
//int len = dp.getLength();
String str = new String(dp.getData(),0,dp.getLength());
//输出到控制台上
System.out.println("from:"+ip+" get:"+str);

}

}

}

发送端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class SendThread implements Runnable {

private DatagramSocket ds;
public SendThread(){}
public SendThread(DatagramSocket ds){
this.ds = ds;
}

@Override
public void run() {
// TODO Auto-generated method stub
while(true){
BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
String line =null;

try {
while((line=br.readLine())!=null){

//数据发送
if(line.equals("88")){
break;
}
byte[] byt = line.getBytes();
int len = byt.length;
InetAddress ip = InetAddress.getByName("192.168.1.108");
DatagramPacket dp = new DatagramPacket(byt,len,ip,12345);
ds.send(dp);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ds.close();
}

}

}

main方法中:
public static void main(String[] args) throws IOException {
//创建两个对象
DatagramSocket send = new DatagramSocket();
DatagramSocket recive = new DatagramSocket(12345);

//创建线程实现类对象并传递DatagramSocket
SendThread st = new SendThread(send);
ReciveThread rt = new ReciveThread(recive);

//创建线程
Thread s = new Thread(st);
Thread r = new Thread(rt);
//开启服务

s.start();
r.start();

}

类的加载和反射
类的加载:

* 根加载:系统自带的.class文件
 * 拓展加载: 拓展功能的其他.class文件
 * System加载: 加载自己写的.class文件
 
反射机制:

加载一个.class,然后通过该文件获取每个class固有的构造方法对象Constructor[] ,成员变量对象Fields[],成员方法对象Method[],
  然后根据这些对象去调用各自的方法,从而对这些对象自身对应的调用(包括赋值,添加参数等),
  通过反射不仅可以获取基本方法还可以获取私有的的各种变量和方法 通过setAccessible(true)可获得访问权限
 
 
  public static void main(String[] args) throws Exception {

//public static Class<?> forName(String className)  throws ClassNotFoundException返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:
//获取一个Student的class文件
Class c = Class.forName("com.reflect.Student");
//获取构造方法
Constructor[] con = c.getDeclaredConstructors();//获取所有的构造方法
for(Constructor cn :con){
System.out.println(cn);
}
//获取单个构造方法
Constructor cn = c.getConstructor(String.class,int.class);
Object obj =cn.newInstance("小学生",10);//创建实例

//获取所有的成员变量包括私有Declared
Field[] all = c.getDeclaredFields();
for(Field a:all){
System.out.println(a);
}
//获取当个变量
Field a =c.getDeclaredField("name");
a.setAccessible(true);
a.set(obj, "all");//这样就设置了一个变量
System.out.println(a);
Student s = (Student)obj;
s.show();

//获取所有的成员方法
Method[] me = c.getDeclaredMethods();
for(Method m:me){
System.out.println(m);
}
//调用成员方法
Method m= c.getDeclaredMethod("method", String.class);
//调用私有的方法 m.setAccessible(true);
m.invoke(obj, "hellow");//这个直接调用了
}

动态代理:可以简单就了解一下

Class c = Class.forName("com.daili.Userimpl");
//创建InvocationHandler对象
InvocationHandler inv = new MyInvocationHandlerimpl(c);
Proxy.newProxyInstance(us.getClass().getClassLoader(), us.getClass().getInterfaces(),inv);

JDBC(Java Database Connectivity)

Java连接数据库基础:
是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API)

Java Application 应用层通过jdbc的驱动(即jdbc的接口实现类)访问数据库
而这些驱动一般由数据库产商提供

JDBC驱动程序:各个数据库厂商根据JDBC的规范制作的 JDBC 实现类的类库

JDBC驱动程序总共有四种类型:
第一类:JDBC-ODBC桥。 
第二类:部分本地API部分Java的驱动程序。 
第三类:JDBC网络纯Java驱动程序。 
第四类:本地协议的纯 Java 驱动程序。//本次采用的 mysql-connector-java-5.1.7-bin.jar
第三、四两类都是纯Java的驱动程序,
因此,对于Java开发者来说,它们在性能、可移植性、功能等方面都有优势。

本地协议的纯 Java 驱动程序:
多数数据库厂商已经支持允许客户程序通过网络直接与数据库通信的网络协议。
这种类型的驱动程序完全使用 Java 编写,通过与数据库建立的 Socket 连接,
采用具体与厂商的网络协议把 JDBC 调用转换为直接连接的网络调用

JDBC URL的标准由三部分组成,各部分间用冒号分隔。 
jdbc:<子协议>:<子名称>
协议:JDBC URL中的协议总是jdbc 
子协议:子协议用于标识一个数据库驱动程序
子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息

mysql的url:(sid表示所使用的数据库)
jdbc:mysql://localhost:3306/sid

oracle的url:
jdbc:oracle:thin:@localhost:1521:sid

SQLServer 数据库连接
jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid

DButils挺好用的,需要导包
c3p0通过加载properties的xml文件,注意xml的命名,来创建线程池,前提要导包
<c3p0-config>

<!-- 这些是基本设置 -->
<named-config name="c3p0_jdbc">
<property name="user">root</property>
<property name="password">java</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/practice</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- 下面是链接池的基本设置 -->
<!-- 如果连接数不足时,向数据库获取的链接数量 -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">5</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">10</property>

<!-- c3p0的Statement -->
<!-- 可维护的Statement个数 -->
<property name="maxStatements">20</property>
<!-- 每个链接可以同时使用的Statement个数 -->
<property name="maxStatementsPerConnection">5</property>

</named-config>
 
</c3p0-config>

下面是一个tool
public class JDBCTools {

//处理事务
/*提交事务*/
public static void commited(Connection con){
if(con!=null){
try {
con.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//回滚事务
public static void rollBack(Connection con){
if(con!=null){
try {
con.rollback();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

//开始事务
public static void begintx(Connection con){
if(con!=null){
try {
con.setAutoCommit(false);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static Connection getConnection() {
//首先要获取mysql的驱动  然后添加到Add to build path
//获取链接,通过配置文件获取信息
Connection con =null;
String driver = null;
Properties proper = new Properties();
String user=null;
String password = null;
String url=null;

try {
//运用类的加载器进行加载

InputStream in = JDBCTools.class.getClassLoader().getResourceAsStream("dababase.properties");

//properities加载配置文件
proper.load(in);
//获取配置文件的键名
user = proper.getProperty("user");
password = proper.getProperty("password");
url = proper.getProperty("url");
driver=proper.getProperty("driver");

//注册驱动,注意这个
Class.forName(driver);

//用DriverManager获取对应的值并返回一个Connection
con = DriverManager.getConnection(url, user, password);

} catch (Exception e) {
e.printStackTrace();
}
return con;
}

//获取对象,将对象添加到表中
//为什么不可是静态的方法,测试哪一个那一个不可以为静态,否则会出现
//initializationError(org.junit.runner.manipulation.Filter)
public static void addToTable(){
Student s = getStudent();
System.out.println(s);
String sql="insert into student(id,name,age,sex) values(?,?,?,?) ";
System.out.println(sql);
insert(sql, s.getId(),s.getName(),s.getAge(),s.getSex());

}

//查询语句 select
public static void seach(String sql) throws SQLException{
Connection con =null;
ResultSet rs=null;
try {
con=getConnection();
rs =con.prepareStatement(sql).executeQuery();
while(rs.next()){
System.out.print(rs.getString(1)+" ");
System.out.print(rs.getString(2)+" ");
System.out.print(rs.getInt(3)+" ");
System.out.print(rs.getString(4)+" ");
}

} catch (Exception e) {
e.printStackTrace();
}finally{
closeAll(con, rs, null);
}

}
@Test
public void Test() throws SQLException{
String sql="select * from student where id<3";
System.out.println(fromTable(sql));
}
//从表中获取一个行并封装为一个学生对象并输出到控制台上
public static List<Map<String,Object>> fromTable(String sql) throws SQLException{
Connection con =null;
PreparedStatement prepared = null;
ResultSet rs = null;//可以获得不同类型的值的结果
ResultSetMetaData rsmd =null;//可以获取列名或者列名的别名的属性 
Student s = new Student();
List<Map<String,Object>> list= new  ArrayList<Map<String,Object>>();
try {

con=getConnection();
prepared=con.prepareStatement(sql);
rs=prepared.executeQuery();
rsmd=rs.getMetaData();

Map<String,Object> values = new HashMap<String,Object>();

while(rs.next()){
for(int i=0;i<rsmd.getColumnCount();i++){
String counmLabel = rsmd.getColumnLabel(i+1);
Object counmValue = rs.getObject(i+1);
values.put(counmLabel, counmValue);
}

}
//反射到学生对象里面
Class<Student> clazz = Student.class;

Constructor<Student> constr = clazz.getDeclaredConstructor();

//反射到学生。。。。对象里面
s =  constr.newInstance();

for(Map.Entry<String, Object> entry : values.entrySet()){

//遍历得到这些字段和所对应的值,然后把它赋值到一个学生对象里面

String filedName=entry.getKey();

Object filedValue = entry.getValue();

Field fd = clazz.getDeclaredField(filedName);
fd.setAccessible(true);
fd.set(s, filedValue);
}

list.add(values);

} catch (Exception e) {
e.printStackTrace();
}finally{
closeAll(con, rs, prepared);
}
return list;
}

//实现改 删除命令
/**

* @param sql 修改 删除 等命令
* @throws SQLException
*/
public static void update(String sql) throws SQLException{
Connection con =null;
PreparedStatement prepared = null;

try {
con=getConnection();
prepared = con.prepareStatement(sql);
prepared.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
closeAll(con, null, prepared);
}
}

/**

* @param sql 针对学生对象的insert 语句
* @param args 可变参数 ,学生类的类型
*/
public static void insert(String sql,Object ...args) {
//占位符+可变参数
Connection con =null;
PreparedStatement prepared = null;
try {
con = getConnection();
prepared = con.prepareStatement(sql);

for(int i=0;i<args.length;i++){
prepared.setObject(i+1, args[i]);
}
prepared.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
closeAll(con, null, prepared);
}
}

public static Student getStudent(){

Scanner sc = new Scanner(System.in);
Student s = new Student();
System.out.println("请输入一个学生对象");

System.out.println("输入id:");
s.setId(sc.next());
System.out.println("输入age:");
s.setAge(sc.nextInt());
System.out.println("输入name:");
s.setName(sc.next());
System.out.println("输入sex:");
s.setSex(sc.next());
return s;

}

//closeall Connection  ResultSet PrepareStement 
//
public static void closeAll(Connection con,ResultSet rs,PreparedStatement prepard){
if(con!=null){
try {
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(prepard!=null){
try {
prepard.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

The summary of Java相关推荐

  1. JAVA性能诊断与调优

    IBM JDK 默认JVM设置: http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp?topic=/com.ibm.java ...

  2. 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

  3. Google App Engine for Java下的URL编码转换问题

    URL编码问题 此部分参考英文资料: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm http://www.w3school ...

  4. 【Notes】《Thinking in Java》【Chapter 11】Part II

    六.Typical uses of I/O streams java.io.;java.io.;java.io.;java.io.;java.io.;java.io.;java.io.;java.io ...

  5. C#调用JAVA接口WSSE方式用WebClient方式

    C#读取JAVA的WSSE接口的调用代码: 用webclient 方式: /// <summary>/// 调用java cxf ws_security加密的服务wcf客户端对应的加密类/ ...

  6. 使用Java解决您的数据科学问题

    Java offers versatility, interoperability, and the chance to zip around Europe in a red vespa. Data ...

  7. [转]深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)...

    以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...

  8. RSS简述 及 Java构造RSS接口

    RSS RSS(简易信息聚合)是一种消息来源格式规范,用以聚合经常发布更新数据的网站,例如博客文章.新闻.音频或视频的网摘.RSS文件包含全文或是节录的文字,再加上发布者所订阅之网摘数据和授权的元数据 ...

  9. Java Lambda(语言篇——lambda,方法引用,目标类型,默认方法,函数接口,变量捕获)

    深入理解Java 8 Lambda(语言篇--lambda,方法引用,目标类型和默认方法) 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout ...

  10. Java 扫描识别条形码图片

    1.条形码扫描识别的实现方法及步骤 本文以Java代码示例介绍如何来扫描和识别条形码图片.这里使用免费的条码工具Free Spire.Barcode for Java,调用BarcodeScanner ...

最新文章

  1. akka---Getting Started Tutorial (Java): First Chapter
  2. 使用ASP生成HTML文件
  3. Mac及Xcode常用快捷键
  4. 模拟手指触摸 Android,TouchLib
  5. 现代软件工程 作业 3 团队作业
  6. Android开发环境搭建与入门Hello World
  7. 第一次当项目经理压力大_项目经理不想被甩锅,你要这样做进度管理
  8. 学习笔记DL003:神经网络第二、三次浪潮,数据量、模型规模,精度、复杂度,对现实世界冲击...
  9. 100 道 Linux 笔试题,能拿90分以上的都去了BAT
  10. FTP链接ubuntu链接被拒绝
  11. 如何获得一个干净的 gnome 开发环境?
  12. 读者推荐 · 一个美观的简历生成器
  13. 利用阿里云邮件推送免费发邮件,每天免费200封,速度快,还高大上
  14. 西门子MM440变频器调试小记
  15. Unity UGUI坐标与世界坐标转换
  16. 微信红包,企业付款到零钱报错:此IP地址不允许调用接口,如有需要请登录微信支付商户平台更改配置 的原因
  17. python任务栏通知区域_PyQT实现通知区域图标和对话气泡
  18. python永久配置pip下载镜像源方法(window版本)
  19. 每日一课 | SQL模糊查找
  20. html+css实现必要等商城页面

热门文章

  1. Unity Shader: Blend混合
  2. TTime::FormatL详解
  3. Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
  4. eclipse下载速度过慢的解决方法
  5. Compose 跨平台的现状
  6. 海洋测绘 知识点 详细
  7. Xcode8 及 iOS 10 的适配
  8. java实现光盘摆渡_一种光盘摆渡机的制作方法
  9. Behavior(行为)
  10. behavior3editor环境搭建