Java快速教程--vamei 学习笔记(进阶篇)
感谢vamei,学习链接:http://www.cnblogs.com/vamei/archive/2013/03/31/2991531.html
Java进阶01 String类
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/08/3000914.html
字符串操作
——————————————————————————————————–
可以用+实现字符串的连接(concatenate),比如:
“abc” + s
字符串的操作大都通过字符串的相应方法实现,比如下面的方法:
方法 效果
s.length() 返回s字符串长度
s.charAt(2) 返回s字符串中下标为2的字符
s.substring(0, 4) 返回s字符串中下标0到4的子字符串
s.indexOf(“Hello”) 返回子字符串”Hello”的下标
s.startsWith(” “) 判断s是否以空格开始
s.endsWith(“oo”) 判断s是否以”oo”结束
s.equals(“Good World!”) 判断s是否等于”Good World!”
==只能判断字符串是否保存在同一位置。需要使用equals()判断字符串的内容是否相同。
s.compareTo(“Hello Nerd!”) 比较s字符串与”Hello Nerd!”在词典中的顺序,
返回一个整数,如果<0,说明s在”Hello Nerd!”之前;
如果>0,说明s在”Hello Nerd!”之后;
如果==0,说明s与”Hello Nerd!”相等。
s.trim() 去掉s前后的空格字符串,并返回新的字符串
s.toUpperCase() 将s转换为大写字母,并返回新的字符串
s.toLowerCase() 将s转换为小写,并返回新的字符串
s.replace(“World”, “Universe”) 将”World”替换为”Universe”,并返回新的字符串
Java进阶02 异常处理
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/09/3000894.html
异常处理是在解决问题,同时也是在制造问题。大型项目中,过多、过细的异常处理往往会导致程序变得一团糟。异常处理的设计并不简单,并需要谨慎使用。
package test; public class Test { public static void main(String[ ] args) { Battery aBattery = new Battery(); aBattery.chargeBattery(0.5); aBattery.useBattery(-0.5); } } class Battery { /** * increase battery */ public void chargeBattery(double p) { // power <= 1 if (this.power + p < 1.) { this.power = this.power + p; } else { this.power = 1.; } } /** * consume Battery */ public boolean useBattery(double p) { try { test(p); } catch(Exception e) { System.out.println("catch Exception"); System.out.println(e.getMessage()); p = 0.0; } if(this.power >= p) { this.power = this.power - p; return true; } else { this.power = 0.0; return false; } } /** * test usage */ private void test(double p) throws Exception // I just throw.don\'t handle { if (p < 0) { Exception e = new Exception("p must be positive"); throw e; } } private double power = 0.0; // percentage of battery }
Java进阶03 IO基础
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/11/3000905.html
package test; import java.io.*; public class Test { public static void main(String[] args) { try { BufferedReader br = new BufferedReader(new FileReader("file.txt")); String line = br.readLine(); while (line != null) { System.out.println(line); line = br.readLine(); } br.close(); } catch(IOException e) { System.out.println("IO Problem"); } } }
Hello World!
Hello Nerd!
package test; import java.io.*; public class Test { public static void main(String[] args) { try { String content = "Thank you for your fish."; File file = new File("new.txt"); // create the file if doesn\'t exists if (!file.exists()) { file.createNewFile(); } FileWriter fw = new FileWriter(file.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw); bw.write(content); bw.close(); } catch(IOException e) { System.out.println("IO Problem"); } } }
Java进阶04 RTTI
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/14/3013985.html
运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制,在Java运行时,RTTI维护类的相关信息。
多态(polymorphism)是基于RTTI实现的。RTTI的功能主要是由Class类实现的。
package test; public class Test { public static void main(String[] args) { Human aPerson = new Human(); Class c1 = aPerson.getClass(); System.out.println(c1.getName()); Human anotherPerson = new Woman(); Class c2 = anotherPerson.getClass(); System.out.println(c2.getName()); // Class c3 = Class.forName("Human"); // System.out.println(c3.getName()); /* * 这句有问题, Class c3 = Class.forName("Human"); */ Class c4 = Woman.class; System.out.println(c4.getName()); } } class Human { /** * accessor */ public int getHeight() { return this.height; } /** * mutator */ public void growHeight(int h) { this.height = this.height + h; } private int height; } class Woman extends Human { /** * new method */ public Human giveBirth() { System.out.println("Give birth"); return (new Human()); } }
Java进阶05 多线程
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/15/3000898.html
多线程(multiple thread)是计算机实现多任务并行处理的一种方式。
在单线程情况下,计算机中存在一个控制权,并按照顺序依次执行指令。单线程好像是一个只有一个队长指挥的小队,整个小队同一个时间只能执行一个任务。
在多线程情境下,计算机中有多个控制权。多个控制权可以同时进行,每个控制权依次执行一系列的指令。多线程好像是一个小队中的成员同时执行不同的任务。
在多线程编程中,要尽力避免竞争条件(racing condition),即运行结果依赖于不同线程执行的先后。线程是并发执行的,无法确定线程的先后,所以我们的程序中不应该出现竞争条件。
创建线程
package test; public class Test { public static void main(String[] args) { NewThread thread1 = new NewThread(); NewThread thread2 = new NewThread(); thread1.start(); //start thread1 thread2.start(); //start thread2 } } /** * create new thread by inheriting Thread */ class NewThread extends Thread { private static int threadID = 0; //shared by all /** * constructor */ public NewThread() { super("ID: " + (++threadID)); } /** * convert object to string */ public String toString() { return super.getName(); } /** * what dors the thread do? */ public void run() { System.out.println(this); } }
Runnable
package test; public class Test { public static void main(String[] args) { Thread thread1 = new Thread(new NewThread(), "first"); Thread thread2 = new Thread(new NewThread(), "second"); thread1.start(); //start thread1 thread2.start(); //start thread2 } } /** * create new thread by implementing Runnable */ class NewThread implements Runnable { /** * convert object to string */ public String toString() { return Thread.currentThread().getName(); } /** * what dors the thread do? */ public void run() { System.out.println(this); } }
售票程序
3个售票亭(Booth)共同售卖100张票(Reservoir)。每个售票亭要先判断是否有余票,然后再卖出一张票。如果只剩下一张票,在一个售票亭的判断和售出两个动作之间,另一个售票亭卖出该票,那么第一个售票亭(由于已经执行过判断)依然会齿形卖出,造成票的超卖。为了解决该问题,判断和售出两个动作之间不能有“空隙”。也就是说,在一个线程完成了这两个动作之后,才能有另一个线程执行。
在Java中,我们将共享的资源置于一个对象中,比如下面r(Reservoir)对象。它包含了总共的票数;将可能造成竞争条件的,针对共享资源的操作,放在synchronized(同步)方法中,比如下面的sellTicket()。synchronized是方法的修饰符。在Java中,同一对象的synchronized方法只能同时被一个线程调用。其他线程必须等待该线程调用结束,(余下的线程之一)才能运行。这样,我们就排除了竞争条件的可能。
在main()方法中,我们将共享的资源(r对象)传递给多个线程:
package test; public class Test { public static void main(String[] args) { Reservoir r = new Reservoir(100); Booth b1 = new Booth(r); Booth b2 = new Booth(r); Booth b3 = new Booth(r); } } /** * contain shared resource */ class Reservoir { private int total; public Reservoir(int t) { this.total = t; } /** * Thread safe method * serialize access to Booth.total */ public synchronized boolean sellTicket() { if(this.total > 0) { this.total = this.total -1; return true; // successfully sell one ticket } else { return false; // no more tickets } } } /** * create new thread by inheriting Thread */ class Booth extends Thread { private static int threadID = 0; // owned by Class object private Reservoir release; // sell this reservoir private int count = 0; // owned by this thread object /** * constructor */ public Booth(Reservoir r) { super("ID: " + (++threadID)); this.release = r; // all threads share the same reservoir this.start(); } /** * convert object to string */ public String toString() { return super.getName(); } /** * what does the thread do? */ public void run() { while(true) { if(this.release.sellTicket()) { this.count = this.count + 1; System.out.println(this.getName() + ": sell 1"); try { sleep((int) Math.random()*100); //random intervals } catch (InterruptedException e) { throw new RuntimeException(e); } } else { break; } } System.out.println(this.getName() + "I sold: " + count); } }
Java进阶06 容器
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/15/3000913.html
package test; import java.util.*; public class Test { public static void main(String[] args) { // Human[] persons = new Human[2]; // array size 2 // persons[0] = new Human(160); // persons[1] = new Human(170); int[] a = {1, 2, 3, 7, 9}; // array size 5 System.out.println(a[2]); String[] names = {"Tom", "Jerry", "Luffy"}; // array size 3 System.out.println(names[0]); int[] aFrom = {1, 2, 3, 7, 9}; // array size 5 int[] aTo = new int[3]; System.arraycopy(aFrom, 1, aTo, 0, 3); System.out.println(aTo[1]); System.out.println("表(List)"); List<String> l1 = new ArrayList<String>(); l1.add("good"); // good l1.add("bad"); // good -> bad l1.add("shit"); // good -> bad -> shit l1.remove(0); // bad -> shit System.out.println(l1.get(1)); System.out.println(l1.size()); System.out.println("集合(set)"); Set<Integer> s1 = new HashSet<Integer>(); s1.add(4); //[4] s1.add(5); //[4,5] s1.add(4); //[4,5] s1.remove(5); //[4] System.out.println(s1); System.out.println(s1.size()); System.out.println("iterator()方法"); List<Integer> l2 = new ArrayList<Integer>(); l2.add(4); l2.add(5); l2.add(2); Iterator i = l2.iterator(); while(i.hasNext()) { System.out.println(i.next()); } System.out.println("Map是键值对的集合"); Map<String, Integer> m1 = new HashMap<String, Integer>(); m1.put("Vamei", 12); m1.put("Jerry", 5); m1.put("Tom", 18); System.out.println(m1.get("Vamei")); /* * Map还提供了下面的方法,来返回一个Collection: * keySet() 将所有的键转换为Set * values() 将所有的值转换为List */ } }
Java进阶07 嵌套类
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/16/3000896.html
内部类
package test; public class Test { public static void main(String[] args) { Human me = new Human("Vamei"); Human him = new Human("Jerry"); Human.Cup myFirstCup = me.new Cup(); Human.Cup mySecondCup = me.new Cup(); Human.Cup hisCup = him.new Cup(); System.out.println(myFirstCup.whosCup()); System.out.println(mySecondCup.whosCup()); System.out.println(hisCup.whosCup()); } } class Human { /** * inner class */ class Cup { public String whosCup() { return name; // access outer field } } /** * constructor */ public Human(String n) { this.name = n; } public void changeName(String n) { this.name = n; } private String name; }
嵌套static类
package test; public class Test { public static void main(String[] args) { Human.Mongolian him = new Human.Mongolian(); him.Shout(); } } class Human { /** * nested class */ static class Mongolian { public void Shout() { System.out.println("Oh...Ho..."); } } }
Java进阶08 GUI
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/17/3000908.html
GUI(Graphical User Interface)提供了图形化的界面,允许用户以图形的方式与系统进行互动。
java布局方式:http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
package test; import javax.swing.*; import java.awt.*; public class Test { private static void createAndShowGUI() { JFrame frame = new JFrame("HelloWorld"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Pane\'s layout Container cp = frame.getContentPane(); cp.setLayout(new FlowLayout()); // create button JButton b1 = new JButton("click me"); JButton b2 = new JButton("shit"); // add buttons cp.add(b1); cp.add(b2); // show the window frame.pack(); frame.setVisible(true); } public static void main(String[] args) { Runnable tr = new Runnable() { public void run() { createAndShowGUI(); } }; javax.swing.SwingUtilities.invokeLater(tr); } }
Java进阶09 事件响应
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/23/3000911.html
package test; import javax.swing.*; import java.awt.event.*; import java.awt.*; public class Test { private static void createAndShowGUI() { JFrame frame = new JFrame("Hello"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Pane\'s layout Container cp = frame.getContentPane(); cp.setLayout(new FlowLayout()); // add interactive panel to Content Pane cp.add(new ButtonPanel()); // show the window frame.pack(); frame.setVisible(true); } public static void main(String[] args) { Runnable tr = new Runnable() { public void run() { createAndShowGUI(); } }; javax.swing.SwingUtilities.invokeLater(tr); } } /** * JPanel with Event Handling */ class ButtonPanel extends JPanel { public ButtonPanel() { JButton yellowButton = new JButton("Yellow"); JButton redButton = new JButton("Red"); this.add(yellowButton); this.add(redButton); /** * register ActionListeners */ ColorAction yellowAction = new ColorAction(Color.yellow); ColorAction redAction = new ColorAction(Color.red); yellowButton.addActionListener(yellowAction); redButton.addActionListener(redAction); } /** * ActionListener as an inner class */ private class ColorAction implements ActionListener { public ColorAction(Color c) { backgroundColor = c; } /** * Actions */ public void actionPerformed(ActionEvent event) { setBackground(backgroundColor); // outer object, JPanel method repaint(); } private Color backgroundColor; } }
Java进阶10 内存管理与垃圾回收
学习链接:http://www.cnblogs.com/vamei/archive/2013/04/28/3048353.html
JVM的垃圾回收是多种机制的混合。JVM会根据程序运行状况,自行决定采用哪种垃圾回收。
我们先来了解“mark and sweep”。这种机制下,每个对象将有标记信息,用于表示该对象是否可到达。当垃圾回收启动时,Java程序暂停运行。JVM从根出发,找到所有的可到达对象,并标记(mark)。随后,JVM需要扫描整个堆,找到剩余的对象,并清空这些对象所占据的内存。
另一种是“copy and sweep”。这种机制下,堆被分为两个区域。对象总存活于两个区域中的一个。当垃圾回收启动时,Java程序暂停运行。JVM从根出发,找到可到达对象,将可到达对象复制到空白区域中并紧密排列,修改由于对象移动所造成的引用地址的变化。最后,直接清空对象原先存活的整个区域,使其成为新的空白区域。