黑马程序员--Java基础--集合、泛型、其他对象(System、Runtime、Math、Date)

来源:互联网 发布:二叉树的遍历算法结果 编辑:程序博客网 时间:2024/05/19 22:46

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

 

1.集合类


1.1为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一 种方式。

1.2数组和集合类同是容器,有何不同?

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。

1.3集合类的特点

1.用于存储对象的容器。
2.集合的长度是可变的。
3.集合中不可以存储基本数据类型值。

2.集合框架

集合容器因为内部的数据结构不同,有多种具体容器。不断的向上抽取,就形成了集合框架。

3.框架的顶层Collection接口

Collection的常见方法:

1.添加

 boolean add(Object obj):

 boolean addAll(Collection coll):

2.删除

 boolean remove(object obj):

 boolean removeAll(Collection coll);

 void clear(); 

3.判断

 boolean contains(object obj):

 boolean containsAll(Colllection coll);

 boolean isEmpty():判断集合中是否有元素。

4.获取:

 int size():

 Iterator iterator():取出元素的方式:迭代器。

 该对象必须依赖于具体容器,因为每一个容器的数据结构都不同。

 Iterator接口就是对所有的Collection容器进行元素取出的公共接口。

迭代是取出集合中元素的一种方式。

因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器。

5.其他:

 boolean retainAll(Collection coll);取交集。

 Object[] toArray():将集合转成数组。

 
4.Collection的两大子接口


|-- List(列表):有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。
|-- Set(集):元素不能重复,无序。

4.1 Collection--->>List

List:特有的常见方法:有一个共性特点就是都可以操作角标。

1.添加

 void add(index,element);

 void add(index,collection);

2.删除;

 Object remove(index):

3.修改:

 Object set(index,element);

4.获取:

 Object get(index);

 int indexOf(object);

 int lastIndexOf(object);

 List subList(from,to);

list集合是可以完成对元素的增删改查。

>>List集合包含:

4.1.1 Vector:内部是数组数据结构,是同步的。增删,查询都很慢。

vector 特有的方法:

1.添加

addElement(Object);

2.获取

Enumeration();

|--addElement(Object);

|--nextElement();

public class VectorDemo {public static void main(String[] args) {Vector v = new Vector();v.addElement("abc1");v.addElement("abc2");v.addElement("abc3");v.addElement("abc4");Enumeration en = v.elements();//vector特有的方法while(en.hasMoreElements()){System.out.println("nextelment:"+en.nextElement());}Iterator it = v.iterator();//共有迭代器while(it.hasNext()){System.out.println("next:"+it.next());}}}


4.1.2.LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。

LinkedList一些常用方法:

1.添加

在此列表的开头插入指定的元素。

void addFirsrt(Object)

Boolean offerFirst(Object)


在此列表的结尾插入指定的元素。

void addLast(Object)

Boolean offerLast(Object)


2.修改

将此列表中指定位置的元素替换为指定的元素。

Object set(int index,Object obj)

3.获取

获取但不移除此列表的第一个元素

Object getFirst():如果此列表为空,则抛异常。

Object peakFirst():如果此列表为空,则返回 null


获取但不移除此列表的最后一个元素

Object getLast():如果此列表为空,则抛异常。

Object  peakLast():如果此列表为空,则返回 null


4.删除

 获取并移除此列表的第一个元素;

Object removeFirst():如果此列表为空,则抛异常。

Object pollFirst():如果此列表为空,则返回 null


获取并移除此列表的最后一个元素;

Object removeLast():如果此列表为空,则抛异常。

Object pollLast():如果此列表为空,则返回 null


/* * 请使用一个LinkedList来模拟一个堆栈或者队列数据结构 * 堆栈:先进后出 * 队列:先进先出 * 创建一个容器 */class DuiLie {private LinkedList list;DuiLie() {list = new LinkedList();}void myAdd(Object obj) {list.addLast(obj);}public Object myGet() {return list.removeFirst();}public Boolean isNull() {return list.isEmpty();}}public class LinkedListTest {public static void main(String[] args) {DuiLie dl = new DuiLie();dl.myAdd("abc1");dl.myAdd("abc2");dl.myAdd("abc3");while (!dl.isNull()) {System.out.println(dl.myGet());}}}

4.1.3 ArrayList:内部是数组数据结构,是不同步的。查询很快。

ArrayList()构造一个初始默然容量为 10 的空列表。

/* * 去除ArrayList中重复元素 *  */public class ArrayListTest {public static void main(String[] args) {// TODO Auto-generated method stub//创建一个ArrayList容器ArrayList al=new ArrayList();al.add("abc1");al.add("abc2");al.add("abc1");al.add("abc1");al.add("abc3");System.out.println(al);al=getSingleElements(al);System.out.println(al);}public static ArrayList getSingleElements(ArrayList al) {// TODO Auto-generated method stub//新建一个ArrayList容器装ArrayList temp=new ArrayList();//获取迭代器Iterator it=al.iterator();while(it.hasNext()){Object obj=it.next();if(!temp.contains(obj))temp.add(obj);}return temp;}}


4.2 Collection--->>set

set:集合中元素不可以重复。

set集合包含:

4.2.1 hashdSet:内部数据结构是哈希表,线程不安全,存取速度快。

HashSet:通过equals方法和hashCode 方法来保证元素的唯一性。

注:如果元素要存储到HashSet中,必须覆盖HashCode和equals方法。

public class HashSetDemo2 {public static void main(String[] args) {HashSet hs = new LinkedHashSet();hs.add(new Person("abc1", 21));hs.add(new Person("abc2", 22));hs.add(new Person("abc2", 23));hs.add(new Person("abc2", 24));hs.add(new Person("abc2", 22));// 会出现两个abc2Iterator it = hs.iterator();while (it.hasNext()) {Person p = (Person) it.next();System.out.println("name:" + p.getName() + ".." + "age:"+ p.getAge());}}}


4.2.2TreeSet:线程不安全,可以对Set集合中的元素进行排序。

TreeSet:通过compareTo或者compare 方法中的来保证元素的唯一性。元素是以二叉树的形式存 放的。

TreeSet排序1:

让元素具备排序功能,元素就必须实现Comparable接口,覆盖compareTo方法。

TreeSet排序2:

用比较器的方法让集合自身具备比较功能,先定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeeSet的构造函数。

/* *对字符串按长度排序  *  */public class TreeSetTest {public static void main(String[] args) {// TODO Auto-generated method stubTreeSet ts = new TreeSet(new ComparatorByLength());ts.add("aaaa");ts.add("gdaa");ts.add("gd");ts.add("hjt");ts.add("zss");Iterator it = ts.iterator();while (it.hasNext()) {System.out.println(it.next());}}} class ComparatorByLength implements Comparator{@Overridepublic int compare(Object o1, Object o2) {// TODO Auto-generated method stubString st1=(String)o1;String st2=(String)o2;int temp=st1.length()-(st2.length());return temp==0?st1.compareTo(st2):temp;} }


4.3 Map

Map:一次添加一对元素,也叫双集合。其实Map集合中存储的是键值对。Map集合中必须保证键值的唯一性。

常用方法:

1.添加

value  put(key,value):返回前一个和key关联的值,如果没有则返回null;

2.判断
boolean containsKey(key)
boolean containsValue(value)
boolean isEmpty();

3.获取
value get(key):通过键获取值,如果没有该键则返回null;当然可以通过是否返回null来判断是否包含指定键。

4.删除
 void clear();清空集合
value remove(key);根据指定的key删除键值对。

注:Map存相同的键值会覆盖。

public class MapDemo {public static void main(String[] args) {Map<Integer,String> map = new HashMap<Integer,String>();map.put(8,"zhaoliu");map.put(2,"zhaoliu");map.put(7,"zhouqi");map.put(6,"niuba");method(map);method_2(map);}public static void method_2(Map<Integer,String> map){//通过值集合取值Collection<String> values = map.values();Iterator<String> it2 = values.iterator();while(it2.hasNext()){System.out.println(it2.next());}/* * 通过Map转成set就可以迭代。 * 找到了另一个方法。entrySet。 * 该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型 */Set<Map.Entry<Integer, String>> entrySet = map.entrySet();Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();while(it.hasNext()){Map.Entry<Integer, String> me = it.next();Integer key = me.getKey();String value = me.getValue();System.out.println(key+"..."+value);}}public static void method(Map<Integer,String> map){//取出map中的所有元素。//原理,通过keySet方法获取map中所有的键所在的Set集合,在通过Set的迭代器获取到每一个键,//在对每一个键通过map集合的get方法获取其对应的值即可。Set<Integer> keySet = map.keySet();Iterator<Integer> it = keySet.iterator();while(it.hasNext()){Integer key = it.next();String value = map.get(key);System.out.println(key+":"+value);}}}


4.4 Map常用的子类

Hashtable:内部结构是哈希表,是同步的,不允许null作为键作为值。

HashMap:内部结构是哈希表,是不同步,允许null作为键作为值。

TreeMap:内部结构是二叉树,是不同步,可以对Map集合的键进行排序。

Properties:用来存储键值对行的配置文件信息。

5.泛型(JDK1.5新特性)

5.1.1 泛型的特点

  1. 提高了程序的安全性
  2. 将运行期遇到的问题转移到了编译期
  3. 省去了类型强转的麻烦
  4. 泛型类的出现优化了程序设计
5.1.2 泛型的使用:

当操作的引用型数据类型不确定的时候就使用泛型<>,将要操作的引用数据类型传入即可,其实泛型<>就是一个用于接收具体引用数据类型的参数范围,在程序中只要用到带有<>的就要明确具体引用数据类型。

5.1.3 泛型的擦除:

泛型技术是给编译器使用的技术,在编译时使用确保了数据类型的安全,运行时会将泛型擦去,生成的class的文件中是不带泛型的,这个称为泛型的擦除(其实是为兼容以前的类加载器)。

5.1.4 泛型的补偿:

运行时通过获取元素的类型进行转换动作,不用使用者再强行转换。

注:当方法是静态的时候,不能访问类定义的泛型,如果静态方法使用泛型,只能将泛型定义在方法上。

5.1.5泛型的上限:

泛型的通配符:?

? extends E:接收E类型或者E的子类型对象。上限!

一般在存储元素时都是用上限,因为取出时都是按照上限类来运算的,不会出现安全隐患。

5.1.6泛型的下限:

? super E :接收E类型或者E的父类型。下限!

通常在对元素进行取出操作时使用下限。

public class MapDemo {public static void main(String[] args) {Map<Integer,String> map = new HashMap<Integer,String>();//<>泛型的使用map.put(8,"zhaoliu");map.put(2,"zhaoliu");map.put(7,"zhouqi");map.put(6,"niuba");//通过值集合取值Collection<String> values = map.values();//<>泛型的使用Iterator<String> it2 = values.iterator();//<>泛型的使用while(it2.hasNext()){System.out.println(it2.next());}}}


6.集合的使用技巧:

1.需要唯一性:Set

需要制定顺序:TreeSet

不需要制定顺序:HashSet

想要一个和存储一致的顺序(有序):LinkedHashSet

2.不需要唯一性:List

需要频繁增删:LinkedList

不需要频繁增删:ArrayList

7.集合框架工具类

7.1.1Collections:里面的方法都是静态的。

常用方法:

 void sort(List<T> list);自然排序

int binarySearch(List<? extends Comparable<? super T>> list, T key):二分法查找

void reverseOrder(List<T> list):反转

void fill(List<? super T> list, T obj):全部替换

void shuffle(List<T> list):随机排列替换


7.1.2 Arrays:里面的方法都是静态的。

常用方法:

asList():将数组转成集合(以调用集合的方法)

注意:

1.如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。 

2.如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。

3.数组的长度是固定的,所以对于集合的增删方法是不可以使用的否则会发生UnsupportedOperationException

7.1.3 Collection:

Object[ ] toArray():将集合转成数组(可以对集合中的元素操作的方法进行限定。不允许对其进行增删。)

<T>[ ] toArray(T[] a):将集合转成数组(可以对集合中的元素操作的方法进行限定。不允许对其进行增删。)

toArray方法需要传入一个指定类型的数组。

如何确认数组长度?

1.如果长度小于集合的size(),那么该方法就创建一个与集合相同size()的数组。

2.如果长度大于集合的size(),难么该方法就使用指定的数组存储集合的元素,其他位置默认为null。

8.增强for(JDK1.5新特性)

 8.1 格式:

for(类型  变量   :Collection集合|数组){...}

8.2 传统for和高级for的区别?

1.传统for可以完成对语句执行很多次,因为可以定义控制循环的增量和条件。

2.高级for是传统for一种简化形式。

3.它必须有被遍历的目标。该目标要是数组,要么是Collection单列集合。

4.对数数组的遍历如果仅仅是获取数组中的元素,可以使用高级for。

5.如果要对数组的角标进行操作建议使用传统for。 

注:不可以直接使用高级for遍历map,但是如果可以将map转成单列的set,就可以用了。

public class ForeachDemo {public static void main(String[] args) {Map<Integer, String> map = new HashMap<Integer, String>();map.put(3, "zhagsan");map.put(1, "wangyi");map.put(7, "wagnwu");map.put(4, "zhagsansan");for (Integer key : map.keySet()) {// 高级forString value = map.get(key);System.out.println(key + "..." + value);}for (Map.Entry<Integer, String> me : map.entrySet()) {// 高级forInteger key = me.getKey();String value = me.getValue();System.out.println(key + ":" + value);}}}


9.可变参数函数(JDK1.5新特性)

函数的可变参数:

其实就是一个数组,但是接收的是数组的元素。自动将这些元素封装成数组。简化了调用者的书写。

注意:可变参数类型,必须定义在参数列表的结尾。

public class ParemterDemo {public static void main(String[] args) {int sum = newAdd(5,1,4,7,3);System.out.println("sum="+sum);int sum1 = newAdd(5,1,2,7,3,9,8,7,6);System.out.println("sum1="+sum1);}public static int newAdd(int a,int...  arr){//可变参数类型int sum = 0;for (int i = 0; i < arr.length; i++) {sum+=arr[i];}return sum;}}

10.静态导入

静态导入:其实导入的是类静态中的静态成员。

import static java.util.Collections.*;//静态导入import static java.lang.System.*;//静态导入public class StaticImportDemo {public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("abc3");list.add("abc7");list.add("abc1");out.println(list);//可省掉类名System的书写sort(list);//可省掉类名Collections的书写System.out.println(list);String max = max(list);System.out.println("max="+max);}}


11.其他对象

11.1System:类中的方法和属性都是静态的。

常见的方法:

long currentTimeMillis();获取当前时间的毫秒值。 

getProperties():获取系统信息

String getProperty(String key):获取指定系统信息

setProperties(Properties props):设置系统信息

String setProperty(String key, String value):设置指定键的系统信息

gc():运行垃圾回收器。

public class SystemDemo {//获取line.separator的系统信息并把它作为一个常量使用private static final String LINE_SEPARATOR = System.getProperty("line.separator");//获取line.separatorpublic static void main(String[] args) {long l = System.currentTimeMillis();//获取当前时间的毫秒值System.out.println(l);System.out.println("hello-"+LINE_SEPARATOR+" world");//给系统设置一些属性信息。这些信息是全局,其他程序都可以使用。 System.setProperty("myclasspath", "D:\\myclass");demo_1();}//获取系统信息并遍历public static void demo_1(){Properties prop = System.getProperties();//获取系统信息Set<String> nameSet = prop.stringPropertyNames();for(String name : nameSet){String value = prop.getProperty(name);System.out.println(name+":"+value);}}}


11.2 Runtime

  Runtime:没有构造方法摘要,说明该类不可以创建对象。

又发现还有非静态的方法。说明该类应该提供静态的返回该类对象的方法。

而且只有一个,说明Runtime类使用了单例设计模式。


常用的方法:

 runtime getRuntime():返回与当前 Java 应用程序相关的运行时对象。

exec("指定程序路径或名称"):执行某个程序

public class RuntimeDemo {public static void main(String[] args) throws IOException, InterruptedException {Runtime rt = Runtime.getRuntime();Process p = rt.exec("qq.exe");//执行某某程序Thread.sleep(4000);//线程等待p.destroy();//杀掉程序}}


11.3 Math

Math:提供了操作数学运算的方法。都是静态的。


常用的方法:

abs():返回一个数的绝对值。

ceil():返回大于参数的最小整数。

floor():返回小于参数的最大整数。

round():返回四舍五入的整数。

pow(a,b):a的b次方。

random():0.0-1.0之间的随机数。

randomDouble():随机数

randomInt():随机数

public class MathDemo {public static void main(String[] args) {double d1 = Math.ceil(12.56);// 12.0double d2 = Math.floor(12.56);// 13.0double d3 = Math.round(12.46);// 12.0System.out.println(d3);Random r = new Random();for (int i = 0; i < 10; i++) {double d = Math.ceil(Math.random() * 10);System.out.println(d);}}}


11.4 Date

1.日期对象和字符串之间的转换

1.1.将日期格式的字符串-->日期对象。

使用的是DateFormat类中的parse()方法。 

1.2.将日期对象-->日期格式的字符串。

使用的是DateFormat类中的format方法。


2.日期对象和毫秒值之间的转换。

2.1毫秒值-->日期对象 : 

1.通过Date对象的构造方法  new Date(timeMillis);

2.还可以通过setTime设置。 

因为可以通过Date对象的方法对该日期中的各个字段(年月日等)进行操作。

2.2 日期对象-->毫秒值:
getTime方法。

因为可以通过具体的数值进行运算。 

public class DateDemo {public static void main(String[] args) throws ParseException {methodDemo_1();methodDemo_2();methodDemo_3();}/*将日期格式的字符串-->日期对象。*使用的是DateFormat类中的parse()方法。 */public  static void methodDemo_3() throws ParseException {String str_date = "2013---8---21";DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);dateFormat = new SimpleDateFormat("yyyy---MM---dd");Date date = dateFormat.parse(str_date);//将日期格式的字符串-->日期对象。System.out.println(date);long time = date.getTime();//日期对象的毫秒值System.out.println(time);}public static void methodDemo_2() {Date date = new Date();//获取日期格式对象。具体着默认的风格。 FULL LONG等可以指定风格。DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);//自定义风格dateFormat = new SimpleDateFormat("yyyy:MM:dd");String str_date = dateFormat.format(date);System.out.println(str_date);}public static void methodDemo_1() {long time = System.currentTimeMillis();//将日期转换成毫秒值Date date = new Date();//将当前日期和时间封装成Date对象。System.out.println(date);Date date2 = new Date(time);//将指定毫秒值封装成Date对象。System.out.println(date2);}}



0 0
原创粉丝点击