首页 > 代码库 > 面向对象基础

面向对象基础

面向过程的写法:
public class Points{
public static void main(String[] args){
qw(1,2);

}
public static void qw(double x1, double y1,){
System.out.println((x1+y1)*2);
}
}
面向对象的写法:
public class Points {
public Points(double x1, double y1) {
this.setX1(x1);
this.setY1(y1);
}
public double x1;
public double y1;
public void setX1(double x11) {
this.x1 = x11;
}
public void setY1(double y11) {
this.y1 = y11;
}
public double getX1(){
return this.x1;
}
public void run() {System.out.println(x1+"\t"+y1)
}
int age;
public void setAge(int newage){
if(newage>150){System.out.println("输入错误,赋值为30");
this.age=30;
}
else{this.age=newage}
}
public static void main(String[] args) {
Points ps = new Points(0,0);
ps.run();
}
// xperson xp = new xperson();
// xp.name="张三";
面向过程:脆弱的、不易维护、扩展性和灵活性差的开发模式。
面向对象:健壮的、易维护、扩展性和灵活性强的开发模式。

Java 面向对象 : Object Oriented 源自于对象的 OO
维护性 -------- 封装
扩展性 ---------继承
灵活性 ---------多态
OOP 面向对象的编程 programming
OOA 面向对象的分析 Analysis
OOD 面向对象的设计 Design
面向对象的概念:利用封装、继承、多态的特性实现程序的可维护性、可扩展性、灵活性。
封装:隐藏成员属性和成员方法以及隐藏成员方法的实现过程。
类: Class 对【对象】的抽象
对象: Object 对【类】的实例
类中的成员:
成员属性:名词
成员方法:动词
抽象:Abstract :抽取事物本质的共性,而忽略事物细节的特性。
使用get、set访问器保护成员属性。
this 关键字 是指调用当前方法的对象自身的成员。
方法的重载:函数名相同、形参的类型或者数量不同。
构造函数:
1)构造函数不允许有返回值
2)构造函数的名称必须和类名一致
构造函数的分类
1.隐式构造函数
java编译器发现一个类没有显示构造函数,那么Java编译器就会自动生成一个没有形参的构造函数。
2.显式构造函数
程序员在类中自定义的构造函数。
注意: 如果一个类有显示构造函数,那么Java编译器就不会再为该类生成隐式构造函数。
静态: static
1.成员属性是在对象被实例化的时候产生的。
静态变量是指对象生成之前就已经存在于数据区
2.静态变量和静态方法可以用类名来访问
3.在静态方法中不能访问成员属性和成员方法,只能访问静态变量和静态方法。
继承:extends
在现有的父类基础上,新增子类继承于该父类,那么该子类就会拥有该父类的所有成员,也可以扩展自己的新成员。
继承实现了程序的扩展性。
注:构造函数不会被子类继承。

子类 ( 派生类) this
父类 ( 超类 ) super

成员方法的重写 Override
在子类中定义一个和父类完全相同的成员方法。子类放弃了父类中该方法的继承。
在派生类中覆盖超类遗传给自己的成员方法。

Java 一个类只能有一个超类,可以用多个派生类。

多态:父类的引用指向了子类的实例
多态实现了程序的灵活性。
多态的使用前提:
1.必须有子类继承父类
2.子类必须要重写父类的方法

final修饰符
final修饰 变量 ---》 常量
final修饰 方法 ---》 该方法不能被重写
final修饰 类 ---》 该类不能被继承

Abstract抽象修饰符
Abstract修饰类 ----》 抽象类
抽象类不能被实例化。
拥有抽象方法的类就必须是抽象类。
抽象类是专门用来被派生类继承的。
派生类继承于抽象超类,必须要实现超类中所有的抽象方法。

Abstract修饰方法 ----》抽象方法
抽象方法只定义了方法的结构,而没有具体的实现过程。
抽象方法是专门用来被派生类重写的。

Interface 接口
Java通过接口实现多重继承的效果。
接口是一系列常量和抽象方法的集合。
类实现接口必须要实现该接口的所有抽象方法。
类先继承父类在实现接口。
接口不能被实例化。
类只能继承一个父类,但可以实现多个接口。
包:package
删除没有用到的包路径 Ctrl+Shift+O

访问修饰符
本类内部 相同包不同类 不同包子类 不同包的不同类
public true true true true
protected true true true false
[default] true true false false
private true false false false

Java异常类 : Exception
错误分两种:
1.错误 error 编译时出错
2.异常 Exception 运行时出错
算术异常:ArithmeticException
异常处理
try结构:尝试去运行可能会产生异常的指令段
catch结构:捕获try代码段中产生的异常
finally:不管进入了try还是catch结构,最终必须要执行的指令段
在方法上throws一个异常的类型,方法的一定条件下throw异常,然后再try-catch;
内部类:
// 内部类的访问特点
// 1.内部类可以直接访问外部类的成员、包括私有
// 2.外部类访问内部成员,必须要创建对象
// 外部类名.内部类名 对象名 = 外部类对象.内部类对象;

// Outer o = new Outer();
// Outer.Inner i = o.new Inner();

Outer.Inner i = new Outer().new Inner();
私有内部类:在外部内创建一个方法public void print(){};包含把私有内部类实例化,方法也输出;
静态成员内部类:
// 外部类名.内部类名 对象名 = 外部类名.内部类对象
Outer3.Inner oi = new Outer3.Inner();
oi.method();

Outer3.Inner2.print();
局部内部类访问局部变量:
外部类里面方法体中有内部类,在方法体内,内部类外实例化,并且输出;
匿名内部类:
匿名内部类:就是内部类的简化写法。
前提:
存在一个类或者接口

格式: new 类名或者接口名(){
重写方法....
}
看作一个实例类;后面可以加.里面方法名;
public class Demo02 {
public static void main(String[] args) {
// 按照要求,补齐代码
// 要求在控制台输出"helloKitty"
Outer2.method().show();
}
}
interface Inter{
public void show();
}
class Outer2{
// 补齐代码
public static Inter method(){
return new Inter(){
@Override
public void show() {
System.out.println("helloKitty");
}
};
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Object最大的类:
Object o = new Object();
System.out.println(o.hashCode());
System.out.println(o.getClass());
System.out.println(o.getClass().getName());
toString 重写
System.out.println(a1.toString());
System.out.println(a1);
//重写的toString方法:
public String toString() {
return "Animal [name=" + name + ", color=" + color + ", age=" + age + "]";
}
.equal重写
public boolean equals(Object obj) {
Animal x = (Animal)obj;//Object强转为当前类
return this.getAge()==x.getAge()&&this.getColor().equals(x.getColor())&&this.getName().equals(x.getName());
}

String类:
public String(byte[] bytes)
先建数组,再new String
public String(byte[] bytes, int index, int length)
public String(char[] value)
public String(char[] value, int index, int length)
public String(String original) 把字符串常量转成字符串
比较:
boolean equals(Object anObject)
boolean equalsIgnoreCase(String anotherString)
boolean contains(String s)
boolean endsWith(String prefix)
boolean startsWith(String prefix) 判断此字符串是否以指定的前缀开始
boolean isEmpty() 是否为空
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

长度:
System.out.println(str1.length());
System.out.println(str1.getBytes().length);
获取字符:
System.out.println(str.charAt(2));
System.out.println(str2.indexOf("a"));返回指定字符在此字符串中第一次出现的索引
!!如果查找不到,那么返回int 值-1;
System.out.println(str2.indexOf("a", 5));返回指定字符串在此字符串中从指定位置的第一次出现的索引
System.out.println(str2.lastIndexOf("cd", 12));倒着来
System.out.println(str.substring(2));截取
System.out.println(str.substring(2, 4));截取 不包括4!!!
byte[] b = str.getBytes();把字符串转成字节数组
char[] toCharArray():把字符串转换成字符数组str.toCharArray()).
static String valueOf(char[] ch):把字符数组转换成字符串String a = String.valueOf();
static String valueOf(int i):把int类型的数据转换成字符串
注意:String类的valueOf方法可以把任意类型的数据转换成字符串
String toLowerCase():把字符串转换成小写
String toUpperCase():把字符串转换成大写
String concat(String str):把字符串拼接
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
A:String的替换功能及案例演示
String replace(char old ,char new )
System.out.println(str.replace("a", ""));
String的去除字符串中空格及案例演示
System.out.println(str.trim());//只能去除最前和最后的字符串
System.out.println("a".compareTo("A")); 等于int 32;
// 根据,把字符串转成数组
String str = "123/.abc/.456/.ggg";
// char[] c1 = str.toCharArray();
// System.out.println(Arrays.toString(c1));
String[] str2 = str.split("/.");
System.out.println(Arrays.toString(str2));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
StringBuffer:
System.out.println(sb3.length());
System.out.println(sb3.capacity()); // 初始容量+字符串长度(长度小于容量,容量就是默认的,之外,加默认)
sb1.append(‘A‘);添加各种数据;
sb2.insert(1, ‘A‘);准确添加数据;
sb1.deleteCharAt(2);删除精确数据;
sb2.delete(0, 4);范围 [0,4);
sb1.replace(4, 12, "xuexi")范围替换[4,12);
sb2.reverse();倒置;反转;
* public String substring(int start):
* 从指定位置截取到末尾
* public String substring(int start,int end):[start,end);
* 截取从指定位置开始到结束位置,包括开始位置,不包括结束位置
* B:注意事项
* 注意:返回值类型不再是StringBuffer本身

互转: * A:String -- StringBuffer
* a:通过构造方法
* b:通过append()方法
* B:StringBuffer -- String
* a:通过构造方法
* b:通过toString()方法
* c:通过subString(0,length);
// String虽然是引用数据类型,但是它作为参数传递时和基本数据类型(值类型)是一样的
StringBuffer不是;
StringBuilder 线程不安全,效率高!
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Arrays:
* public static String toString(int[] a)
* public static void sort(int[] a)
* public static int binarySearch(int[] a,int key)排好序之后才能用
int -- String
* a:和""进行拼接
* b:public static String valueOf(int i)
* c:int -- Integer -- String(Integer类的toString方法())
String -- int
* a:String -- Integer -- int(i=Integer.valueOf(str).intValue();)
* public static int parseInt(String s) int i = Integer.parseInt(str);???
* JDK5的新特性自动装箱和拆箱
* Integer ii = 100;
* ii += 200;
* C:注意事项
* 在使用时,Integer x = null;代码就会出现NullPointerException。
* 建议先判断是否为null,然后再使用。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
正则表达式
* 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则。有自己特殊的应用。
* A:字符类
String regex = "[1-9]\\d{4,14}";
System.out.println(str.matches(regex));正则表达式在后面;验证前面的是否是true;
* [abc] a、b 或 c(简单类)
* [^abc] 任何字符,除了 a、b 或 c(否定)
* [a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
* [a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
* [a-z&&[def]] d、e 或 f(交集)
* [a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
* [a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
* A:预定义字符类
* . 任何字符(与行结束符可能匹配也可能不匹配)
* \d 数字:[0-9]
* \D 非数字: [^0-9]
* \s 空白字符:[ \t\n\x0B\f\r]
* \S 非空白字符:[^\s]
* \w 单词字符:[a-zA-Z_0-9]
* \W 非单词字符:[^\w]
###08.04_常见对象(数量词)
* A:Greedy 数量词
* X? X,一次或一次也没有
* X* X,零次到多次
* X+ X,一次或多次
* X{n} X,恰好 n 次
* X{n,} X,至少 n 次
* X{n,m} X,至少 n 次,但是不超过 m 次
正则表达式的分割功能
* String类的功能:public String[] split(String regex)
String[] arr = str.split("\\.");
A:正则表达式的替换功能
String str = "我我....我...我.要...要要.要..要学....学学..学.编..编编.编.程.程.程..程";
// 去掉字符串中的点.
String str1 = str.replaceAll("\\.", "");
// System.out.println( str.replaceAll("\\.+", ""));

System.out.println(str1.replaceAll("(.)\\1+", "$1")); // $1 代表第一组的内容???
* String类的功能:public String replaceAll(String regex,String replacement)
System.out.println(str.replaceAll("\\d", ""));
A:正则表达式的分组功能
* 捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
*
1 ((A)(B(C)))
2 (A
3 (B(C))
4 (C)

组零始终代表整个表达式。
正则表达式的获取功能
String regex = "1[345789][0-9]{9}";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);正则表达式在前,需要查找的字段在后

while (m.find()) {
System.out.println(m.group());
}
* public static void gc()
* public static void exit(int status)
* public static long currentTimeMillis() long startTime = System.currentTimeMillis();1478323526401
* pubiic static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) System.arraycopy(arr1, 0, arr2,0, arr1.length);

* A:BigInteger的概述
* 可以让超过Integer范围内的数据进行运算
* B:构造方法
* public BigInteger(String val)
* C:成员方法
* public BigInteger add(BigInteger val) // +
* public BigInteger subtract(BigInteger val) // -
* public BigInteger multiply(BigInteger val) // *
* public BigInteger divide(BigInteger val) // (除) 余数remainder
* public BigInteger[] divideAndRemainder(BigInteger val) // 取除数和余数

* A:BigDecimal的概述
* 由于在运算的时候,float类型和double很容易丢失精度,演示案例。
* 所以,为了能精确的表示、计算浮点数,Java提供了BigDecimal
* 不可变的、任意精度的有符号十进制数。
* B:构造方法
* public BigDecimal(String val)
* C:成员方法
* public BigDecimal add(BigDecimal augend)
* public BigDecimal subtract(BigDecimal subtrahend)
* public BigDecimal multiply(BigDecimal multiplicand)
* public BigDecimal divide(BigDecimal divisor , 2, BigDecimal.ROUND_UP)
BigDecimal divisor , 2, BigDecimal.ROUND_UP:!!!!ROUND_HALF_UP
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* A:Random类的概述
* 此类用于产生随机数如果用相同的种子创建两个 Random 实例,
* 则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。
* B:构造方法
* public Random()
* public Random(long seed)
* C:成员方法
* public int nextInt()
* public int nextInt(int n)(重点掌握)
Random r = new Random();
for (int i = 0; i < 1000; i++) {
System.out.println(r.nextInt(100)); // 0~99的随机数
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* A:Date类的概述
* 类 Date 表示特定的瞬间,精确到毫秒。
* B:构造方法
* public Date()
Date date = new Date();
syso是当前时间;
settime(0)那么是1970.0.0
gettime()是毫秒
* public Date(long date)
* C:成员方法
* public long getTime(1000)毫秒
* public void setTime(long time)
***DateFormat df = DateFormat.getDateInstance();
String str = df.format(date);看成格式刷
System.out.println(str);2016-11-4
* B:SimpleDateFormat构造方法
* public SimpleDateFormat()
* public SimpleDateFormat(String pattern)yyyy年MM月dd日 HH:mm:ss格式yyyy/MM/dd HH:mm:ss
DateFormat df = DateFormat.getDateInstance();
// String str = df.format(date);
// System.out.println(str);
2016-11-4

SimpleDateFormat sdf = new SimpleDateFormat();
String str = sdf.format(date);
System.out.println(str);
16-11-4 下午7:57


* C:成员方法
* public final String format(Date date)
* public Date parse(String source)
DateFormat df = DateFormat.getDateInstance();
System.out.println(dt.getTime());
System.out.println(System.currentTimeMillis());获取现在时间!
String str ="2016年11月11日 11:11:11";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");

try {
Date d= sdf.parse(str);
System.out.println(d);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* A:System类的概述
* System 类包含一些有用的类字段和方法。它不能被实例化。
* B:成员方法
* public static void gc()
* public static void exit(int status)
* public static long currentTimeMillis()
System.arraycopy(arr1, 0, arr2, 0, arr1.length);
* pubiic static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Calendar类:
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH) + 1); // 一月是0 , 12月是11
// XXXX年XX月XX日 星期X
System.out.println(c.get(Calendar.YEAR) + Contain.YEAR
+ getNum(c.get(Calendar.MONTH) + 1) + Contain.MONTH
+ getNum(c.get(Calendar.DAY_OF_MONTH))
+ Contain.DAY + Contain.HALF_SPASE+ getWeek(c.get(Calendar.DAY_OF_WEEK)));

}

public static String getWeek( int week){

String str[] = { "", "星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };

return str[week];
}

public static String getNum(int num) {
return num > 9 ? "" + num : "0" + num;
}
* A:成员方法
* public void add(int field,int amount)
* public final void set(int year,int month,int date)
System.out.println(c.get(Calendar.YEAR));
c.add(Calendar.MONTH, 2);
// c.add(Calendar.YEAR, 2);

// c.set(Calendar.YEAR, 2010);
// c.set(Calendar.MONTH , 7);
c.set(2011, 12 , 11);
Calendar c=Calendar.getInstance();
System.out.println(c.get(Calendar.YEAR));
c.set(2017, 10,9);
System.out.println(c.get(Calendar.YEAR));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Collection:
基本功能演示
Collection c = new ArrayList();
boolean add(E e)
boolean remove(Object o)
void clear()
boolean contains(Object o)
boolean isEmpty()
int size() c.

add方法如果是List集合,一直都是返回ture,因为List集合中是可以存储重复元素,
如果是set集合,当存储重复元素的时候,就会放回false

ArrayList的父类的父类重写了toString方法,所以在打印对象引用时,输出的不是Object类中的toString方法
带All的功能演示
boolean addAll(Collection c)
boolean removeAll(Collection c)
boolean containsAll(Collection c)是否包含集合
boolean retainAll(Collection c)取交集 如果调用集合有改变就返回true
// 如果调用集合没有改变就返回false
迭代器
如果不用迭代器,用for 记得转型
Iterator it = c.iterator(); //获取迭代器的引用
while(it.hasNext()) { //集合中的迭代方法(遍历)
System.out.println(it.next());
public static void main(String[] args) {
Collection coll = new ArrayList();

coll.add(new Student("张三",23)); //Object obj = new Student("张三",23);
coll.add(new Student("李四",24));
coll.add(new Student("王五",25));
coll.add(new Student("赵六",26));

Object[] arr = coll.toArray(); //将集合转换成数组

for (int i = 0; i < arr.length; i++) {
Student s =(Student)arr[i];
System.out.println(s.getName() + ", " + s.getAge());
ArrayList:
List list = new ArrayList();
list.add(new Student("001", "张三", 18));

// 使用size方法获取元素个数
for (int i = 0; i < list.size(); i++) {
// 向下转型
Student s = (Student)list.get(i);
System.out.println(s.getStudentNo() + " , " + s.getStudentName() + " , " + s.getStudentAge());
// ListIterator 是接口,不能被实例化
ListIterator it= list.listIterator() ; 当你要在列表里加东西 。size会改变,用这个迭代器
while(it.hasNext()){
String str = (String)it.next();
if(str.equals("world")){
it.add("javaee");
}
System.out.println(str);
}
ListIterator的hasPrevious必须.next方法使用过后:
while(it.hasPrevious()){
System.out.println(it.previous()); // 获取元素,并且下标向前移动
}

Vector类概述
* public void addElement(E obj)
* public E elementAt(int index)
* public Enumeration elements()
* C:案例演示
* Vector的迭代
* @param args
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) {
Vector v = new Vector();
v.addElement("a");
v.addElement("b");
v.addElement("c");

// 获取指定索引(下标)的元素
System.out.println( v.elementAt(1) );

// 获取Vector中的所有元素
Enumeration e = v.elements();
// 是否存在下一个元素
while (e.hasMoreElements()) {
// 获取元素
System.out.println(e.nextElement());
}
ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)
LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。

Vector和ArrayList的区别
Vector是线程安全的,效率低
ArrayList是线程不安全的,效率高
共同点:都是数组实现的
ArrayList和LinkedList的区别
ArrayList底层是数组结果,查询和修改快
LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
共同点:都是线程不安全的
* B:List有三个儿子,我们到底使用谁呢?
查询多用ArrayList
增删多用LinkedList
如果都多ArrayList
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* A:泛型通配符<?>
* 任意类型,如果没有明确,那么就是Object以及任意的Java类了
* B:? extends E
* 向下限定,E及其子类
* C:? super E
* 向上限定,E及其父类
for(String str : list){
System.out.println(str);
}
}
A:静态导入概述
* B:格式:
* import static 包名….类名.方法名;
* 可以直接导入到方法的级别
* C:注意事项
* 方法必须是静态的

// 直接使用Animal类中的成员属性和方法
System.out.println(pinzhong);
say(6);
// speak();// 方法必须是静态
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
A:可变参数概述
* 定义方法的时候不知道该定义多少个参数
* B:格式
* 修饰符 返回值类型 方法名(数据类型… 变量名){}
* C:注意事项:
* 这里的变量其实是一个数组
* 如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个
public static void print(int... arr, String str) {
// for (int i : arr) {
// System.out.println(i);
// }
// }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* Arrays工具类的asList()方法的使用
* Collection中toArray(T[] a)泛型版的集合转数组
* @param args
*/
public static void main(String[] args) {
// 通过数组工具类转为集合

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
LinkedList类概述
* B:LinkedList类特有功能
* public void addFirst(E e)及addLast(E e)
LinkedList<> s=new linkedList<>();
* public E getFirst()及getLast()
* public E removeFirst()及public E removeLast()
* public E get(int index);
// int 的包装类127以上就new 所以false
Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1 == i2);
System.out.println(i1.equals(i2));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
HashSet:
* 1.HashSet原理
* 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
* 当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象
* 如果没有哈希值相同的对象就直接存入集合
* 如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存
* 2.将自定义类的对象存入HashSet去重复
* 类中必须重写hashCode()和equals()方法
* hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
* equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储

// HashSet中已经存在元素"a",Set中的元素是唯一的,所以这里就添加不成功,返回false
// 字典顺序输出 默认
* HashSet存储自定义对象保证元素唯一性
HashSet<Person> hs = new HashSet<>();
public class Person2 implements Comparable<Person2> {
public int compareTo(Person2 o) {
// 返回等于0的时候,集合中就只有一个元素
// 返回大于0的时候,集合中就有多个元素(顺序存储)
// 返回小于0的时候,集合中就有多个元素(倒序存储)
// int num = this.age - o.age; // 主条件
// return num == 0 ? this.name .compareTo(o.name) : num; // 名字是副条件
// return this.name .compareTo(o.name); // 按名字排序
return this.name.length() - o.name.length(); // 按名字的长度排序
对象重写 hashcode 和equals

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
LinkedHashSet:
* B:案例演示
* LinkedHashSet的特点
* 可以保证怎么存就怎么取
* 底层是链表实现的,是set中唯一一个能够保证怎么存就怎么取的集合对象。
* 因为是HashSet的子类,所以也保证元素的唯一性,与hashset原理是一样的。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* TreeSet存储自定义对象
*
* 二叉树:负数存储在左边,正数存储在右边,相等0不存储
* compareTo方法在TreeSet集合中如何存储元素完全是取决于compareTo方法的返回值
对象重写 hashcode 和equals和compare
// 创建TreeSet集合
TreeSet<String> ts = new TreeSet<>(new CompareByLen());
class CompareByLen implements Comparator<String> {

@Override
public int compare(String o1, String o2) {
// 按名字的长度排序
return o1.length() - o2.length();
}

}
* 1.特点
* TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
* 2.使用方式
* a.自然顺序(Comparable)
* TreeSet类的add()方法中会把存入的对象提升为Comparable类型
* 调用对象的compareTo()方法和集合中的对象比较
* 根据compareTo()方法返回的结果进行存储
* b.比较器顺序(Comparator)
* 创建TreeSet的时候可以制定 一个Comparator
* 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
* add()方法内部会自动调用Comparator接口中compare()方法排序
* 调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
* c.两种方式的区别
* TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
* TreeSet如果传入Comparator, 就优先按照Comparator
也可以定义一个新类implements Compare... 然后重写compare方法,然后再丢进新建hashset的构造函数括号里;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
集合框架(Map集合概述和特点)
* A:Map接口概述
* 查看API可以知道:
* 将键映射到值的对象
* 一个映射不能包含重复的键
* 每个键最多只能映射到一个值
* B:Map接口和Collection接口的不同
* Map是双列的,Collection是单列的
* Map的键唯一,Collection的子体系Set是唯一的
* Map集合的数据结构只针对键有效,跟值无关;Collection集合的数据结构是针对元素有效
* A:Map集合的功能概述
* a:添加功能
* V put(K key,V value):添加元素。
* 如果键是第一次存储,就直接存储元素,返回null
* 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
* b:删除功能
* void clear():移除所有的键值对元素
* V remove(Object key):根据键删除键值对元素,并把值返回
* c:判断功能
* boolean containsKey(Object key):判断集合是否包含指定的键
* boolean containsValue(Object value):判断集合是否包含指定的值
* boolean isEmpty():判断集合是否为空
* d:获取功能
* Set<Map.Entry<K,V>> entrySet():
keyset
* V get(Object key):根据键获取值
* Set<K> keySet():获取集合中所有键的集合
* Collection<V> values():获取集合中所有值的集合
* e:长度功能
* int size():返回集合中的键值对的个数
###13.03_集合框架(Map集合的遍历之键找值)
* A:键找值思路:
* 获取所有键的集合
* 遍历键的集合,获取到每一个键
* 根据键找值
* A:键值对对象找键和值思路:
* 获取所有键值对对象的集合
* 遍历键值对对象的集合,获取到每一个键值对对象
* 根据键值对对象找键和值
entrySet(); //获取所有的键值对象的集合
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Iterator<Entry<String, Integer>> it = entrySet.iterator();//获取迭代器
HashMap集合
LinkedHashMap的特点
* 底层是链表实现的可以保证怎么存就怎么取
统计字符串中每个字符出现的次数 -----------------map的映射
HashMap和Hashtable的区别
* Hashtable是JDK1.0版本出现的,是线程安全的,效率低,HashMap是JDK1.2版本出现的,是线程不安全的,效率高
* Hashtable不可以存储null键和null值,HashMap可以存储null键和null值
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* B:Collections成员方法
public static <T> void sort(List<T> list)
public static <T> int binarySearch(List<?> list,T key)
public static <T> T max(Collection<?> coll)
public static void reverse(List<?> list)
public static void shuffle(List<?> list)// 洗牌
Collections.shuffle(poker);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
小结:
arrayslist : 数组 增删慢 查询快
linkedlist 链表
vector 数组
hashset 不重复 自然顺序 hashcode equals implements comprable 重写的是compareto
linkedset 保证顺序
treeset 二叉法 可自定义排序 建类implements comprator 构造函数括号新类 compare
hashmap (键,值)
linkedmap
treemap
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* File(String parent, String child):根据一个目录和一个子文件/目录得到File对象
* File(File parent, String child):根据一个父File对象和一个子文件/目录得到File对象
public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了
* public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了
* public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来
重命名和删除功能
* public boolean renameTo(File dest):把文件重命名为指定的文件路径
* public boolean delete():删除文件或者文件夹
* B:重命名注意事项
* 如果路径名相同,就是改名。
* 如果路径名不同,就是改名并剪切。
* C:删除注意事项:
* Java中的删除不走回收站。
* 要删除一个文件夹,请注意该文件夹内不能包含文件或者文件夹
* public boolean isDirectory():判断是否是目录
* public boolean isFile():判断是否是文件
* public boolean exists():判断是否存在
* public boolean canRead():判断是否可读
* public boolean canWrite():判断是否可写
* public boolean isHidden():判断是否隐藏
* public String getAbsolutePath():获取绝对路径
* public String getPath():获取路径
* public String getName():获取名称
* public long length():获取长度。字节数
* public long lastModified():获取最后一次的修改时间,毫秒值
* public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
* public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
private static void getFiles(File file1) {
// 获取指定目录下的所有文件对象
File[] filearr = file1.listFiles();
for (File file : filearr) {
// 判断是否是文件
if (file.isFile() && file.getName().endsWith(".java")) {
// 输出
System.out.println(file.getName());
}else if( file.isDirectory() ){
getFiles(file);
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1 int a ;
// 将每次读到的字节赋值给变量,并判断是否是-1
while ((a = fis.read()) != -1) {
// 输出变量值
System.out.println((char)a);
}
// 关闭流
fis.close();
2 // 创建一个数组,要和文件大小一样
byte[] b = new byte[fis.available()];

// 将文件中的内容全部一次性读取到数组中(在内存)
fis.read(b);

// 把内存中数组写放到输出流
fos.write(b);
3 byte[] arr = new byte[1024 * 8 ];
int len;
// 使用fis.read(),结果不正确,要使用fis.read(arr)方法
while ((len = fis.read(arr)) != -1) {
fos.write(arr, 0, len);
}

// 创建字节输出流
// 如果指定文件不存在,就自动创建
// 虽然写入到文件中,但是文件中原来的内容都被覆盖了
// FileOutputStream fos = new FileOutputStream("bbb.txt");
// 写入的内容会添加到文件中内容的末尾
FileOutputStream fos = new FileOutputStream("bbb.txt" , true);
BufferedOutputStream bos = new BufferedOutputStream(fos);

int len;
while( (len = bis.read()) != -1 ){
bos.write(len);
flush()方法
* 用来刷新缓冲区的,刷新后可以再次写出 写在write之后
* 写出回车换行 write("\r\n".getBytes());
// 异或加密
bos.write(b ^ 123);// 密钥
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FileWriter fw = new FileWriter("eee.txt" , true);
fw.write("abcd");
fw.write("\r\n");
fw.write("你好!");
fw.close();
在try()中创建的流对象必须实现了AutoCloseable这个接口,如果实现了,在try后面的{}(读写代码)执行后就会自动调用,流对象的close方法将流关掉
FileReader
* FileReader类的read()方法可以按照字符大小读取
FileReader fr = new FileReader("aaa.txt"); //创建输入流对象,关联aaa.txt
int ch;
while((ch = fr.read()) != -1) { //将读到的字符赋值给ch
System.out.println((char)ch);
char[] arr = new char[1024*8]; //创建字符数组
while((len = fr.read(arr)) != -1) { //将数据读到字符数组中
fw.write(arr, 0, len); //从字符数组将数据写到文件上
}
BufferedReader br = new BufferedReader(new FileReader("aaa.txt")); //创建字符输入流对象,关联aaa.txt
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt")); //创建字符输出流对象,关联bbb.txt

int ch;
while((ch = br.read()) != -1) { //read一次,会先将缓冲区读满,从缓冲去中一个一个的返给临时变量ch
bw.write(ch); //write一次,是将数据装到字符数组,装满后再一起写出去
}
BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));
String line;
while((line = br.readLine()) != null) {
bw.write(line);---------------------------------------------------------------------------
//bw.write("\r\n");
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
LineNumberReader是BufferedReader的子类, 具有相同的功能, 并且可以统计行号
* 调用getLineNumber()方法可以获取当前行号
* 调用setLineNumber()方法可以设置当前行号
*
LineNumberReader lnr = new LineNumberReader(new FileReader("aaa.txt"));
String line;--------------------------------------------------------------------------------------------
lnr.setLineNumber(100); //设置行号
while((line = lnr.readLine()) != null) {
System.out.println(lnr.getLineNumber() + ":" + line);//获取行号
}

lnr.close();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
###16.05_IO流(使用指定的码表读写字符)
* FileReader是使用默认码表读取文件, 如果需要使用指定码表读取, 那么可以使用InputStreamReader(字节流,编码表)
* FileWriter是使用默认码表写出文件, 如果需要使用指定码表写出, 那么可以使用OutputStreamWriter(字节流,编码表)
*
BufferedReader br = //高效的用指定的编码表读
new BufferedReader(new InputStreamReader(new FileInputStream("UTF-8.txt"), "UTF-8"));
BufferedWriter bw = //高效的用指定的编码表写
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GBK.txt"), "GBK"));
int ch;
while((ch = br.read()) != -1) {
bw.write(ch);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
// 创建双列集合Map
Map<Character , Integer> map = new TreeMap<>();
// 读取文件中字符,存储到Map中
int ch;
while( (ch = br.read()) != -1 ){
char c = (char)ch;
// 判断当前获取到的c是否在map中存在
if( map.containsKey(c) ){
map.put(c, map.get(c) + 1);
} else {
map.put(c, 1);
}

// map.put(c, map.containsKey(c) ? map.get(c) + 1 : 1);

}
// 关闭输入流
br.close();

// 创建输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("times.txt"));
// 循环Map集合
for(Character key : map.keySet() ){

// if(‘\t‘ == key){
//
// }else if(‘\r‘ == key){
//
// }

switch (key) {
case ‘\t‘:
// 写入到文件中
bw.write("\\t" + "=" + map.get(key));
break;
case ‘\r‘:
// 写入到文件中
bw.write("\\r" + "=" + map.get(key));
break;
case ‘\n‘:
// 写入到文件中
bw.write("\\n" + "=" + map.get(key));
break;

default:
// 写入到文件中
bw.write(key + "=" + map.get(key));

}
bw.newLine();
}
// 关闭流
bw.close();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FileOutputStream fos = new FileOutputStream("copy2.mp3");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy5.jpg"));
FileWriter fw = new FileWriter("bbb.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));
String c;
while ((c = br.readLine()) != null) { // 没有换行
bw.write(c);
// 添加新行
bw.newLine(); // 跨平台
// bw.write("\r\n"); // 只在Windows下有用
}
InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"), "UTF-8");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "GBK");
LineNumberReader lnr = new LineNumberReader(new FileReader("aaa.txt"));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

面向对象基础