util包

util包是java的工具包,即这里面包含了很多工具类:Arrays、Scanner、时间日期、集合...

util也是使用比较多的一个包,但java默认没有在程序里面引入,使用这个包里面的东西,需要单独导包。

比如使用Arrays 需要 import java.util.Arrays

如果使用这个包里面的类比较多, import java.util.*;

Data类

Date类表示是时间,精确到毫秒。 如果程序里面需要此时的时间,或者需要一个时间对象,可以实例化一个Date对象出,Date中包装时间。

构造方法:

new Date() --- > 无参的构造方法,表示此时时间。即将此时的日期时间封装成一个Date对象。这个时间是程序执行的系统的时间,即程序在哪执行 获得的就是哪个主机的时间。

new Date(String str) ---> 将一个字符串转成Date对象,(过时了)

str必须满足固定的格式: “yyyy/mm/dd hour:minute:second” 如果不是这个格式,编译可以通过, 但运行的时候报参数异常。

new Date(long x) ---> 将整数x转成一个时间对象。x代表了从1970-1-1 经过的毫秒数

代码:Date d = new Date(System.currentTimeMillis()); d代表此时时间

new Date(int y,int m ,int d) --->将整数y m d 转成一个date对象,

y代表y+1900代表年份 m+1代表月份 d天

普通方法:

toString() ---> 按照某个格式将date对象转成字符串。 星期 月份 日期 时分秒 年

toLocalString()---->按照本地的格式显示时间日期

get***() ---> 从时间日期对象中获取 年份、月份、。。。。

set***()------> 设置日期对象中的 年份、月份、。。。

getTime()----->将这个时间日期对象转成毫秒数,毫秒代码从1970-1-1,经过的毫秒数

如果有一个字符串需要转date对象,可以使用Date的构造方法,传入字符串,但这个方法过时了,不推荐使用,java推荐的是使用DateFormate对象来转换:

String str = "2012年12月12日";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年dd月mm日");
Date d = sdf.parse(str);

Calendar

Calendar也是一个时间日期类,但它是一个抽象类,只能使用它的子类或者他的静态的方法。Calendar里面提供了一个正好返回Calendar对象的静态方法。即如果需要一个Calendar对象则代码:

Calendar c = Calendar.getInstance();

创建一个Calendar对象后,这个对象里面包含了很多日期相关的信息,如果直接打印对象,数据不方便使用,所以如果需要什么数据,就是get方法从对象里面获取。

c.get( 字段名 ) 字段名是一个整数,Calendar提供了静态的字段。

c.set(字段名,值)

Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 1999);
c.set(Calendar.MONTH,9-1);
c.set(Calendar.DATE,9);

c.add(字段名n,数字x) 将这个日期的某个字段加值

//用户输入年份 和月份  打印月历
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入年份和月份:");
		int year = sc.nextInt();
		int month = sc.nextInt();
		Calendar c = Calendar.getInstance();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONDAY, month-1);
		c.set(Calendar.DATE, 1);
		int x = c.get(Calendar.DAY_OF_WEEK);
		//System.out.println(x);
		System.out.println("日\t一\t二\t三\t四\t五\t六");
		int n = c.getActualMaximum(Calendar.DAY_OF_MONTH);
		int count = 0;
		for(int i = 0;i < x-1;i++){
			count++;
			System.out.print("\t");
		}
		for(int i = 1;i <= n ;i++){
			count++;
			System.out.print(i + "\t");
			if(count % 7 == 0){
				System.out.println();
			}
		}

Random类

Math里面有个方法是 Math.random(), 这个方法只能随机0到1之间的小数,如果需要随机整数,则通过这个方法修改。

如果需要随机一个小写字母: (char)(Math.random()*26 + 97)

随机0到100之间的整数: (int)(Math.random()*100)

如果需要随机一个boolean类型的值?

Random类中提供了很多随机的方法:比如随机小数、随机整数、随机boolean类型 等等。。。

构造方法:

new Random() ----> 创建一个无参的Random对象,可以随机数据。

new Random(long n) ---> 创建一个Random对象,放入一个种子,种子的作用是保证程序多次运行,随机的数字 一样。

方法:

r.nextInt() ----> 随机一个整数,可能是任何一个整数,这个数可能很大,

如果是需要一个0-8之间的整数: r.nextInt() % 8

r.nextInt(int n) ----> 随机0到n之间的整数。

r.nextDouble() --->随机0到1之间的小数,与Math.random()功能一样。

r.nextBoolean() --->随机一个boolean类型

集合Collection

集合与数组一样,是一个存放数据的容器。但数组有缺点就是一旦数组创建后,它的长度就不能改变,即数组不能添加新位置,或者删除某个位置;数组还有一个缺点就是只能固定类型的数据,即数组定义的时候已经确定了数组只能放什么类型的数据。 集合正好弥补了数组的这两个缺点,即集合是一个长度没有限制,存放的数据也没有限制的容器。

java的3大集合: List Set Map (3个都是接口,即如果需要集合应该去实例化他们的实现类)

List 和 Set 来自同一个接口 Collection,数据是一个一个的向里面保存。 Map中的数据需要成对的向里面放入。

List中保存的数据是有顺序的,而且可以保存相同的数据。 Set中保存的数据是没有顺序的,而且不能保存相同的数据。

在List里面常用的有两个实现类: ArrayList LinkedList

ArrayList 以数组为基础,即他们保存的数据在内存中连续的,添加和删除会消耗时间,但它的查询很快。

LinkedList是以链表为基础,他们保存的数据在内存中不是连续的。查询很慢,但添加和删除数据很快

List

ArrayList

实现了List接口,继承了AbstractList。有序的且可以放重复元素的collection。以数组为基础,保存的元素在内存中的位置连续,查询比较快。 它不是线程安全的,即它的方法不是同步的。

构造方法:

new ArrayList() 创建一个ArrayList对象,初始容量为10.元素的长度为0.

new ArrayList(n) 创建一个初始容量为n的ArrayList对象。

功能方法:

list.size() : 返回集合的长度,即元素的个数

list.add(Object o) : 将对象o放入集合list中,o可以是任何数据(复合类型,如果放入基本类型,则会变成基本 类型的包装对象) add方法是将o放在集合的后面。

list.add(index,o) : 将对象o放入到集合的第index个位置,这个位置之前的内容和它后面的东西都整体向后移动 一位。

list.addAll(index,Collection c) : 将集合c中的数据全部取出,放入到index位置,后面的数据向后移动

list.clear() : 清除集合中的元素

list.clone() : 将这个集合克隆一个副本。是浅克隆,即集合中的元素没有被克隆。克隆出的集合和之前的集 合,他们的元素还是指向同一个位置

list.get(index) : 获取集合中的第index位置的元素,index从0开始,到list.size()-1结束,超过这个返回出现集合 下标越界异常。 从集合中获得的元素都是Object类型,如果确定这个元素的类型,可以使用强转

list.contains(o) : 判断集合list中是否包含了对象o,返回的是boolean类型。这个判断是使用对象的equals方法 判断的,即如果集合中10个元素,需要判断x是否在里面,则使用x的equals方法一个一个的去比 较里面的10个元素

list.indexOf(o) : 返回o在list中第一次出现的位置,如果list中没有o则返回-1. (list.lastInexOf())

list.isEmpty(): 判断此集合是否没有元素

list.remove(index) : 移除集合list中的第index位置上的元素,这个位置后面的元素都向前移动。返回的是被移 除的对象

ArrayList list = new ArrayList();
list.add("abc");
list.add("def");
list.remove(1);   ---> 这行代码的返回值是字符串“def”

list.remove(o) : 移除集合list中的o对象,返回的是一个boolean类型,true代表移除成功,false代表移除失败

ArrayList list = new ArrayList();
list.add(9);
list.add(19);
list.add(3);
list.add(99);
list.remove(3);----> 移除的是数字3元素还是第3个元素?  移除的是第3个元素。
                      如果是需要移除元素3,则使用list.remove(Integer(3))

list.set(index,o) : 将集合中的第idnex个元素修改为o对象。

list.toArray() : 将这个集合list转成Object类型的数组。

LinkedList

list的链表实现。存放的数据在内存中不是连续的。以链表的形式保存,所以它的插入和删除比较快,不用改变其他元素的位置。null可以当做元素添加。同时LinkedList也不是线程安全的。

构造方法:

new LinkedList() ---> 创建一个空的list容器。(不需要指定容量)

普通方法:

list.size() 长度

添加:

list.add(o) 添加对象o到集合的末尾

list.add(index,o) 添加对象o到集合的第index位置。

list.addFirst(o) : 添加对象o到集合第一个位置 等同于list.add(0,o)

list.addLast(o) : 添加对象o到集合的最后一个位置 等同于add(o)

list.push(o): 将对象o添加到第一个位置 : 等同于 list.add(0,o)

查找:

list.get(index) : 获取集合的第index位置的元素

list.getFirst()

list.getLast();

list.element(): 获取第一个元素(不移除) list.get(0) 或者list.getFirst()

list.peek() 获取第一个元素(不移除) list.get(0) 或者list.getFirst() 或者 list.element()

list.peekFrist() : 获取第一个元素(不移除 ) 如果集合的长度是0,没有异常,直接返回null

list.peekLast() : 获取最后一个元素

删除:

list.remove() : 获取并删除第一个元素

list.remove(index) : 删除指定位置index上面的元素,返回被删除的对象.如果集合没有元素,删除时会出异常

list.remove(o) : 删除集合中的对象o ,返回boolean

list.removeFirst() :获取并删除第一个元素

list.removeLast(): 获取并删除最后一个元素

list.poll () : 删除第一个元素,并返回 等同于: list.remove(0) 如果集合没有元素,删除时不会出异常

list.pollFirst():删除第一个元素,并返回

list.pollLast() :删除最有一个元素,并返回

list.pop() : 获取并删除第一个元素, list.remove(0)

修改:

list.set(index ,o) : 将集合中的第index位置上的元素修改为o

Vector

Vector 也ArrayList 类似,都是继承abstractList,都实现了List接口。 Vector与ArrayList 最大的区别是 Vector是线程安全的,ArrayList是非线程安全的。Vector的效率低。

构造方法和普通方法与ArrayList一样。

如果需要保证数据的线程安全就使用Vector,其他一般的情况都使用ArrayList

Set

一个无序的Collection,且里面元素没有重复。这个重复是指元素之间的equals方法都是返回false。

set是一个集合,常用的set有: HashSet TreeSet

HashSet

实现了Set接口,继承了AbstractSet抽象类。基于哈希码的Set集合。Set是无序的,即放入的顺序与获取的顺序不一样,而且里面放入的元素的顺序不是恒久不变的。 HashSet不是线程安全的,即它的方法不是同步的。很多线程可以同时去修改一个HashSet。 如果是在多线程里面使用HashSet就需要自己来控制同步。

构造方法:

new HashSet(); ----> 创建一个空元素的Set容器。初始容量是16,加载因子是0.75

new HashSet(int n); ----> 创建一个初始容量为n的Set容器

普通方法:

set.size() : 返回容器里面放入元素的个数

set.add(o) : 将对象o放入集合set中,返回一个boolean类型,表示添加成功或失败,放入o已经存在集合里面 就添加失败,这个o与set里面每个元素都equals比较,都返回false,表示不在里面。

set.clear() : 清除set中的所有元素,长度为0

set.contains(o) : 判断对象o是否在集合set中,o对象与集合中的每个元素都 hashcode不一样,且equals也为 false,则表示o不在里面

set.remove(o) : 移除集合set中的o对象。返回boolean表示成功或者失败。 set中的remove没有通过下标移除 的方法,因为set没有顺序、没有下标

set.iterator(); : 将set转成一个迭代器,返回的是一个迭代器对象。

迭代器Iterator

从set中取值,不能使用普通的for循环去取每一个值,因为set没有下标。但可以将set集合转一个迭代器。

Iterator it = set.iterator();
it就是一个迭代器。

Iterator里面只有3个方法:

next() : 取出迭代器里面的下一个元素 (如果下一个元素没有了,报异常)

hasNext(): 判断是否有下一个元素 (如果返回真 可以继续使用next取元素)

remove() : 移除当前迭代器里面的元素

如果又一个set集合,要取出它的所有元素
Iterator it = set.iterator();
while(it.hasNext()){
	System.out.println(it.next());
}

Iterator迭代器正在迭代一个集合的过程中,不能去集合里面添加或者删除数据;只能迭代完后再添加或者删除。

或者迭代的过程中使用迭代器的删除功能。

TreeSet

TreeSet也是线程不安全的集合。它里面不能放入null作为元素。

TreeSet: 一种有顺序的Set集合,不是元素添加的顺序,是按照元素的自然顺序排序。

TreeSet里面放入的元素必须能排序。即TreeSet里面所有的元素之间可以比较大小。

TreeSet里面放入的元素最终使用通过comparTo方法比较大小。即如果对象具有comparTo方法就可以放入这个集合里面,比如String、Integer、Double

如果一个对象能放入TreeSet里面,则在设计类的时候需要实现Comparable接口,实现里面comparTo方法,TreeSet才可以比较对象的大小,然后排序。

Map

Map也是一个集合,但它里面放入的元素需要成对保存。Map也称为键值对。即它的一个元素有两个对象一个是键一个是值。Map中的键kay是不能重复,但它的值value可以重复。

HashMap

HashMap是Map常用的实现类。即如果程序中需要一个Map,则可以去创建HashMap来使用。Map里面添加的数据是成对的出现,HashMap中可以将null作为键和值一起保存。同时HashMap不是线程安全的,效率比较高。HashMap放入的元素没有顺序。

常用的构造方法:

new HashMap() 创建一个初始容量16,加载因子0.75的空map集合。

功能方法:

map.put(k,v) ----> 将对象k和v作为一个元素放入map中。方法的返回值是:如果这个k是第一次放入,则返回 null,如果这个k以前放过,则这个函数返回的k对应的之前的v。

map中的k不能重复,如果放入值的时候,k已经存在map中,则后面v会覆盖前面的v。

map.size() ----> 获取map的长度,即map中元素的个数

map.containsKey(k) --> 判断这个map中是否有指定键k

map.containsValue(v)-->判断这个map中是否有指定的值v

map.get(k) ---> 通过键k或者对应的值v,如果没有这个键k则返回null。

map.isEmpty()---> 判断这个map是否没有元素

map.keySet() --> 取出map里面所有的键k,组成一个set容器。

map.remove(k) --> 通过一个键k移除map中的一个元素。如果这个键k存在,则返回是这个键对应的值,如果没 有这个键k,则返回null。

map中的键和值可以是任何类型,但一般是将整数或者字符串作为键。值可以是任何数据。

Hashtable

早期的Map的实现。它是线程安全的,所以效率低。 Hashtable不能放入null作为键和值,会报空指针异常。

Stack(栈)

继承了Vector,是Vector的子类,也属于List。 用来保存数据的 堆栈。特征是FILO:First In Last Out 即先进后出。将数据放入Stack里面 先放入的数据最后取出。(LIFO)

构造方法:

new Stack() : 创建一个空的堆栈。

普通方法:

peek() --> 获取这个集合中顶部的数据,但不移除

pop() ----> 获取集合顶部的数据,并移除

push(o) ----> 将对象o放入集合的顶部

Collections

如果在定义一个集合的时候就知道这个集合里面放入的具体的数据,可以不用创建一个集合再一个一个的add数据,可以使用Arrays的静态方法asList。

List list = Arrays.asList( 具体的数据 );

Collection是一个接口,Collections是一个类。Collections是用来操作集合的工具类型,类似于Arrays是操作数组的工具类一样,方法都是静态的,直接Collections.方法名 使用。

常用的方法:

Collections.addAll(c, o...) 将后面的数据o(可以有多个) 全部添加到c集合里面

Collections.binarySearch(c,o) : 使用二分查找,去集合c里面判断是否有对象o 。局限在 集合c中的元素能排 序才可以使用二分查找。(集合中的元素能比较大小,即定义类的时候实习了 Comparable接口)

Collections.copy(c1,c2) : 将c2集合中的数据,一个一个的放入c1集合里面,从c1的第一个位置开始,覆盖c1里 面的值。

Collections.fill(c,o) : 使用o数据来填充c集合的每个位置。即将集合c的每个位置上的数据修改为o。

Collections.max(c) : 查询c集合中的最大值。 c集合中必须放入可以比较的元素

Collections.replaceAll( c, x,y ) : 将集合c中的所有x值 使用y来替换。

Collections.reverse(c) :将集合c中的元素顺序反转

Collections.sort(c) : 将集合c中的元素从小到大排序

Collection 与Collections有什么区别?

Properties

Properties是一个工具类,它继承了Hashtable,Hashtable是一个Map,所以Properties也是一个Map集合。

它的作用一般是使用Properties对象去获取一个Properties文件中的数据。Properties文件一般是放配置文件。

Properties  p = new Properties();//创建工具类对象
p.load(new FileInputStream("a.properties"));//使用对象去加载配置文件
p.get("addr"); //在对象里面 通过键 去获取值

泛型

集合相对于数组来说,有两个优点: 1、长度没有限制,可以不停的扩充。 2、放入的元素的类型没有限制,即一个集合里面什么类型的数据都可以放进去。

因为集合里面什么类型的数据都可以放入,则在从这个集合中取数据时候,无法知道原始类型,即使知道它的原始类型,在取出数据后还需要强转回去。 一般一个集合或者容器里面放入数据都相同的类型。

有了泛型后就可以约束集合里面只能放入指定的类型数据,好处是取数据的时候不再需要强转了,直接就是泛型定义的类型。

集合里面使用泛型:

语法是定义集合的时候 使用尖括号包含类型, 这个类型只能是复合类型,如果是需要放基本类型的数据,就是基本类型的包装类。

list里面: 例如: 定义一个集合,它里面只能放入字符串:

List();

Set里面,定义一个Set容器,它里面只能放入Student对象

Set ();

Map里面, 定义一个map容器,它里面的键是整数,值是字符串

Map <Integer,String> map = new HashMap <Integer,String> ();

foreach

for循环的另一种语法。

for循环基本语法是for( ; ; ){}

for循环的另一种语法: for( : ){ }

foreach的作用就是去容器里面取数据,所以foreach只用在去数组或者集合里面取数据,其他地方不会使用。

语法:

for(  类型  变量名  :  容器名  ){
    //循环体,可以使用变量
}

容器名就是foreach去哪取数据。

foreach只能取数据,不能往容器中放数据。

图形界面

gui swing

JFrame: JFrame的布局是边界布局,JFrame将自己分成 东南西北中,5部分。向JFrame里面放入组件的时候默认都是放在中间,如果JFrame的四周没有组件,则中间的组件就拉伸到整个Frame。可以在放入组件的时候指定位置

JFrame jf = new JFrame();
		jf.setBounds(500, 100, 500, 500);		
		jf.setDefaultCloseOperation(3);		
		
		JButton jb = new JButton("点击");
		jf.add(jb);		
		
		JButton jb2 = new JButton("点击2");
		jf.add(jb2,BorderLayout.NORTH );	
		JButton jb3 = new JButton("点击3");
		jf.add(jb3,BorderLayout.EAST );
		
		jf.setVisible(true);

JFrame中最多只能放5个组件。一般没有将组件直接放在JFrame,而是放在JPanel里面 再将JPanel放入JFrame里面。

可以去掉一个容器的布局。

如果JFrame没有布局,则在向Frame里面放入组件的时候,这个组件需要指定大小和位置。

JPanel,是java图形界面中的面板。,一般将组将放入其中,再将Panel放入Frame。 JPanel的布局默认是flowLayout,往它里面放入组件时,默认放在第一行中间,如果第一行显示不下,在到第二行中间。。。

如果需要将组件排列很整齐,可以设置容器的布局是GridLayout,网格布局。

jp.setLayout( new GridLayout( 5,5 )) ---> 设置jp的布局是一个5行5列

jp.setLayout( new GridLayout( 5,5,1,1 )) ---> 设置jp的布局是一个5行5列,行和列的间距是1个像素

JFrame不能设置背景颜色,其他的组件或者容器都可以设置背景颜色。

JPanel是一个面板,它里面有一个paint方法,paint是一个画图的方法,方法带一个形参Graphic 画笔,但默认的方法里面没有画东西。如果自己的图像界面需要去Jpane里面画东西,就需要重写这个方法,如果想重写就需要去继承java提供的JPanel类,然后再重写paint方法。

Graphic 画笔可以画 : 椭圆、矩形、直线、弧线、图片、字符串

例如: 画直线 g.drawLine(x,y,x2,y2)

画椭圆: g.drawOval(x,y,w,h)

画矩形: g.drawRec(x,y,w,h)

如果是画实心的就将draw改为fill

组件

常见组件:

JButton JTextField JLable JPasswordField

单例模式

单例模式是项目程序在运行的过程中某个类只能实例化一个对象,整个程序运行的时候使用的对象都是同一个。

设计单例模式的过程:

1、构造方法私有化

2、对外提供一个静态的方法,这个静态方法里面就可以调用自己的构造方法了

3、静态的属性,属性就是当前类的类型,静态方法将这个属性赋值

4、外部如果需要对象,就找这个类的静态方法,静态方法提供对象。静态方法将这个静态属性对象返回

单例模式有两种实现方式:

懒汉模式

懒汉模式是说类很懒,当整个类加载的时候,如果没有调用静态方法,则静态的属性先不实例化,如果确定你需要使用的时候再实例化。

public class People {

	private static People p;
	private   People(){
		
	}	
	public static People getInstance(){
		if(p == null){
			p = new People();
		}
		return p;
	}	
}

饿汉模式

在类加载的时候就将这个静态属性初始化了,即已经准备好了对象。

public class People {
	private static People p = new People();
	private   People(){
		System.out.println("实例化了People对象");
	}
	
	public static People getInstance(){
		return p;
	}
	
}

内部类

内部类: 即一个类A的定义在另一个类B的里面,则类A称为类B的内部类。

类的里面可以定义类,但方法里面的里面不能再定义方法。

如果一个类A要去使用另一个类B的属性或者方法,则就可以将类A的定义放在类B的里面,让A是B的内部类。这时内部类就可以直接使用外部类的属性和方法了。

内部类的分类:

1、成员内部类

class A{
	private int x = 1;
	public void a(){
		int x = 2;
		System.out.println("aaaa");
		
	}
		
	访问修饰符 class B{
		private int x = 3;
		public void a(){
			int x = 4;
			System.out.println(x);
		}
	}	
}
//类B是类A的成员内部类
//如果是A里面需要使用B对象:
//则A里面可以直接:
B b = new B();

//如果其他地方需要创建B对象,还必须将创建A对象
//语法:
A a = new A();
A.B  b = a.new B();		
//或者:		
A.B  b2 = new A().new B();

将一个类的定义当做这个类里面的一个属性来定义。 这种成员内部类,如果需要在其他地方创建内部类,则还必须将创建外部类。

class C{
	int x = 5;
}
class D{
	//int x = 6;
}

class A extends C{
	//private int x = 1;
	public void a(){
		int x = 2;
		System.out.println("aaaa");
		
	}
	
	
	class B extends D{
		//private int x = 3;
		public void a(){
			//int x = 4;
			System.out.println(x);
		}
	}
	
}

//一个方法里面在使用一个变量的时候,先去这个方法里面寻找是否定义了方法的局部变量,如果方法里面没有定义再去当前类里面寻找是否定义了属性,如果当前类中没有定义这个属性,再去当前类的父类里面寻找,如果当前类的父类中没有,再去当前类的外部类中寻找属性,如果外部类没有再去外部类的父类中寻找。

2、静态内部类

在成员内部类的前面加static关键字,就变成了静态内部类。

class A{
    static class B{
        
    }
    
}
//静态内部类在创建的时候不需要创建外部类
A.B b = new A.B();

这种静态的内部类不能使用外部类非静态的属性和方法。

静态内部类很少使用。

3、方法局部内部类

将一个类的定义放在另一个类的方法里面。

class A{
    public void method(){
        class B{
            public void method2(){
                
            }
        }
    }
    
}

方法里面定义的局部内部类,只能给这个方法使用。方法里面定义的类也可以使用外部类的属性和方法。

4、匿名内部类

匿名是没有名字,即定义一个类,而类没有名字。

匿名内部类一般定义的时候就实例化使用,而且只能实例化一次。