Download presentation
Presentation is loading. Please wait.
1
COMMON JAVA JAVA数据结构与常用类库简介
Bingoo
2
JAVA类加载
3
Java Classloading Why do we care? So… what identifies a class?
Because if we’re gonna write code at runtime, we’d better know how to load and use it… Because we don’t really understand classes So… what identifies a class? Its name Its package Its classloader It means that We can have multiple instances of a class loaded at the same time Two instances of the same class from different classloaders are not compatible and not assignable Static variables are static only in the context of a classloader, not globally as we’re always told
4
Java Classloading So what is this classloader? Bootstrap classloader
A Java class (subclass of java.lang.ClassLoader), responsible for loading other classes used by the JVM Classloaders are arranged as a tree Bootstrap classloader Loads the Java system jre/lib/resources.jar – series of resource files jre/lib/rt.jar – the java.*, javax.*, etc packages jre/lib/sunrsasign.jar jre/lib/jsse.jar – secure socket extension jre/lib/jce.jar – Java cryptography extension jre/lib/charsets.jar jre/classes The important stuff is in rt.jar – the base Java classes
5
Java Classloading Commandline Java App Tomcat (6)
Bootstrap classloader Loads only bootstrap.jar and tomcat-juli.jar Ext classloader Application/ System classloader Loads Tomcat commons library jars Loads the Application Jars from the classpath Application/ System classloader Common classloader Loads jars in the webapp lib directory WAR 1 classloader WAR 2 classloader
6
自定义类加载器加载一个类的步骤
7
ClassNotFoundException and NoClassDefFoundError
ClassNotFoundException comes when JVM tries to load a class at runtime dynamically means you give the name of class at runtime and then JVM tries to load it and if that class is not found in classpath it throws ClassNotFoundException While in case of NoClassDefFoundError the problematic class was present during Compile time and that's why program was successfully compile but not available during runtime by any reason.
8
aopalliance-1.0.jar asm-3.3.jar asm-commons-3.3.jar asm-tree-3.3.jar axis-1.4.jar bcprov-jdk jar cglib-nodep-2.2.jar commons-beanutils jar commons-codec-1.5.jar commons-collections-3.2.jar commons-discovery-0.4.jar commons-fileupload jar commons-httpclient-3.1.jar commons-io jar commons-lang-2.1.jar commons-logging jar commons-net-2.2.jar commons-pool-1.6.jar commons-ssh jar dom4j jar ems-consumer SNAPSHOT.jar fastjson jar freemarker jar guava-12.0.jar hadoop-core-0.20-append-r jar hbase jar hessian jar ibatis-sqlmap M01.jar javassist GA.jar jline jar jmockit jar jsch jar jsr jar junit jar kafka jar Linkage-EcsCommon jar log4j jar ntfPlat-mailsend jar ntfplat-send jar ognl jar PageSecurity jar phw-all jar ProxyForEcsSms-1.0.jar scala-library jar slf4j-api jar slf4j-log4j jar solr-solrj jar spring jar spring-beans jar spring-context jar spring-context-support jar spring-core jar spring-web jar spring-webmvc jar spymemcached jar struts2-convention-plugin jar struts2-core jar struts2-json-plugin jar wsdl4j jar xerces jar xwork-core jar zkclient-0.1.jar zookeeper jar
9
JAVA Exception
11
几种设计异常的最佳实践 (Best Practises for Designing the API)
选择Checked还是Unchecked的几个经典依据 Exception的封装问题 如无必要不要创建自己的Exception 不要用Exception来作流程控制 不要轻易的忽略捕获的Exception 不要简单地捕获顶层的Exception
12
三种”情景”导致异常的抛出 编程错误导致(Exception due Programming errors)
这种情景下,异常往往处于编程错误(如:NullPointerException 或者 IllegalArgumentException),这时异常一旦抛出,客户端将变得无能为力。 客户端代码错误导致(Exception due client code errors) 客户端试图调用API不允许的操作 资源失败导致(Exception due to resource failures) 如内存不足或网络连接失败导致出现异常等。这些异常的出现客户端可以采取相应的措施来恢复应用程序的继续运行。
13
Java中异常的类型 Checked and Unchecked Exceptions
A checked exception is one that will be checked by the compiler for a surrounding try/catch block if that method have a throws clause An unchecked exception, also called a RuntimeException, does not require programmer intervention with a try/catch block Either there is nothing we can do with this type of problem (sun) Or, this type of problem can be remedied by fixing code For example, an ArrayIndexOutOfBounds
14
Checked or Unchecked exception
问自己一个问题,“如果这种异常一旦抛出,客户端会做怎样的补救?” 如果客户端可以通过其他的方法恢复异常,那么这种异常就是checked exception; 如果客户端对出现的这种异常无能为力,那么这种异常就是Unchecked exception; 尽量使用unchecked exception来处理编程错误;譬如:NullPointerException , IllegalArgumentException 和 IllegalStateException
15
保护封装性(Preserve encapsulation)
不要让你要抛出的checked exception升级到较高的层次。 例如,不要让SQLException延伸到业务层。业务层并不需要(不关心?)SQLException。 转变SQLException为另外一个checked exception,如果客户端并不需要恢复这种异常的话; 转变SQLException为一个unchecked exception,如果客户端对这种异常无能为力的话(多数情况);
16
使用异常最佳实践 总是要做一些清理工作(Always clean up after yourself)
如果使用一些资源例如数据库连接或者网络连接,请记住要做一些清理工作(如关闭数据库连接或者网络连接) 要用try-finally来做必要的清理工作 不要使用异常来控制流程(Never use exceptions for flow control) 不要忽略异常 当有异常被抛出的时候,如果你不想恢复它,那么你要毫不犹豫的将其转换为unchecked exception,而不是用一个空的catch块或者什么也不做来忽略它,以至于从表面来看象是什么也没有发生一样。 不要捕获顶层的Exception unchecked exception都是RuntimeException的子类,RuntimeException又继承Exception,因此,如果单纯的捕获Exception,那么你同样也捕获了RuntimeException,它将忽略所有的异常,包括unchecked exception. Log exceptions just once Logging the same exception stack trace more than once can confuse the programmer examining the stack trace about the original source of exception. So just log it once.
17
Add Java Exception Breakpoint
18
Guava Throwables try { someMethodThatCouldThrowAnything(); } catch (IKnowWhatToDoWithThisException e) { handle(e); } catch (Throwable t) { Throwables.propagateIfInstanceOf(t, IOException.class); Throwables.propagateIfInstanceOf(t, SQLException.class); throw Throwables.propagate(t); }
19
@Annotations
20
Annotation Definition
Structured Data Comparable to records in OCaml @interface MyAnnotation { String value(); // member int i() default 123; // member w. default value } @interface MarkerAnnotation { // annotation without any members
21
Annotation Usage @MyAnnotation(value="text", i=456)
void method() { … } // default value for i: 123 @MyAnnotation(value="text") void method2() { … } // special case for members called "value" @MyAnnotation("text") void method3() { … } // parenthesis can be omitted if no members @MarkerAnnotation void method4() { … }
22
Annotation Members @interface MyAnnotation {
int intMember(); // primitives String stringMember(); // strings Class classMember(); // class literals SomeEnum enumMember(); // enums // annotions OnlyThreadWithName annotMember(); // arrays of the above OnlyThreadWithName[] arrayMember(); }
23
Annotation Targets in Java 5
@A package some.package.name; @B class MyClass { @C Object field; @D Object param) { field = param; } @F Object method() { @G Object localVar = field; return localVar;
24
The Target annotation @Target(ElementType.TYPE)
—can be applied to any element of a class @Target(ElementType.FIELD) —can be applied to a field or property @Target(ElementType.METHOD) —can be applied to a method level annotation @Target(ElementType.PARAMETER) —can be applied to the parameters of a method @Target(ElementType.CONSTRUCTOR) —can be applied to constructors @Target(ElementType.LOCAL_VARIABLE) —can be applied to local variables @Target(ElementType.ANNOTATION_TYPE) —indicates that the declared type itself is an
25
告知程序如何处理@Retention java.lang.reflect.AnnotatedElement接口
public Annotation getAnnotation(Class annotationType); public Annotation[] getAnnotations(); public Annotation[] getDeclaredAnnotations(); public boolean isAnnotationPresent(Class annotationType); Class、Constructor、Field、Method、Package等类别,都实现了AnnotatedElement接口
26
Java Logging
27
Logging use-cases debugging the software during development
help diagnose bugs during production trace access for security purposes create data for statistical use etc
28
History System.out.println() System.err.println() e.printStackTrace()
29
Components Level/ Priority Aplicaction Logger 1..* Appender Filter
Layout
30
descendant logger name. PS: 大小写敏感
Logger Named Hierarchy A logger is said to be an ancestor of another logger if its name followed by a dot is the prefix part in the descendant logger name. PS: 大小写敏感 root com.site.software com.site.software.model com.site.software.model.dao com.site.software.model.dao.PersonDAOImpl com.site.software.view com.site.software is an ancestor logger of the descendant com.site.software.model.dao ● ●com.site.software is the parent logger of the child com.site.software.model
31
A logger may be assigned to a level.
Levels A logger may be assigned to a level. Properties configuration file log4j.rootLogger=ERROR log4j.logger.com.site.software=INFO XML configuration file Java configuration file Logger.getRootLogger().setLevel(Level.ERROR); Logger.getLogger(“com.site.software”).setLevel(Level.INFO); levels are ordered TRACE < DEBUG < INFO < WARN < ERROR < FATAL ●
32
Level/ Priority FATAL: Displays messages of situations that probably will abort the application. ERROR: Displays error messages that are unwanted but not interrupt the application. WARN: Displays messages from dangerous regions for the application, or certain operations use not recommended. INFO: Displays information messages about the execution of the application, or important events. DEBUG: Shows debug messages for the application. (Used in development time) ALL: Show all posts OFF: Disables all messages.
33
The inherited level for a given logger L, is equal to
Level Inheritance The inherited level for a given logger L, is equal to the first non-null level in the logger named hierarchy, starting at L and proceeding upwards in the hierarchy towards the root logger. Assigned Inherited Level level Logger Name root com.site.software com.site.software.model com.site.software.model.dao com.site.software.model.dao.PersonDAOImpl com.site.software.view ERROR WARN INFO null ERROR WARN INFO
34
Level继承1 Logger name Assigned level Effective level root DEBUG X none
X.Y X.Y.Z Logger name Assigned level Effective level root ERROR X INFO X.Y DEBUG X.Y.Z WARN
35
Level继承2 Logger name Assigned level Effective level root DEBUG X INFO
X.Y none X.Y.Z ERROR Logger name Assigned level Effective level root DEBUG X INFO X.Y none X.Y.Z
36
Logging Request A log request of level p in a logger configured (either assigned or inherited, whichever is appropriate) with level q, is enabled if p >= q. import org.apache.log4j.Logger; public class PersonDAOImpl { private final Logger LOG = Logger.getLogger(PersonDAOImpl.class); public PersonDAOImpl() { LOG.debug("You can't see me in the log because debug < INFO"); LOG.info("You will see me in the log because info = INFO"); LOG.warn("You will see me in the log because warn > INFO");
37
Appenders A logger may be assigned to an appender: a named
output destination your log messages are forwarded to. # The root logger logs to the console log4j.rootLogger=ERROR, con # The com.site.software logger logs to a file log4j.logger.com.site.software=INFO, FileApp # The con appender will log in the console log4j.appender.con=org.apache.log4j.ConsoleAppender #The FileApp appender will log in a file log4j.appender.FileApp=org.apache.log4j.FileAppender
38
Appenders
39
Each enabled logging request for a given logger L
Appender Additivity Each enabled logging request for a given logger L will be forwarded to all the appenders in that logger LA as well as all the appenders higher HA in the logger named hierarchy Logger Name root com.site.software com.site.software.model com.site.software.model.dao com.site.software.view LA con null FileApp, c d e HA con FileApp, c, con
40
Additivity Flag root A1 not applicable x A-x1, A-x2 true
Logger Name Attached Appenders Additivity Flag Output Targets Comment root A1 not applicable Since the root logger stands at the top of the logger hierarchy, the additivity flag does not apply to it. x A-x1, A-x2 true A1, A-x1, A-x2 Appenders of "x" and of root. x.y none x.y.z A-xyz1 A1, A-x1, A-x2, A-xyz1 Appenders of "x.y.z", "x" and of root. security A-sec false No appender accumulation since the additivity flag is set to false. Only appender A-sec will be used. security.access Only appenders of "security" because the additivity flag in "security" is set to false.
41
Layout Conversion Pattern
Each appender has a layout component responsible for formatting log messages accordingly to conversion patterns. log4j.appender.con=org.apache.log4j.ConsoleAppender log4j.appender.con.layout=org.apache.log4j.PatternLayout log4j.appender.con.layout.ConversionPattern=%d [%t] %-5p %m (%c:%L)%n Produced logs: :29:11,996 [main] INFO You will see me in the log because info = INFO (com.site.software.model.dao.PersonDAOImpl:10) :29:11,997 [main] WARNYou will see me in the log because warn > INFO (com.site.software.model.dao.PersonDAOImpl:11)
42
A lot of Appenders and Layouts
● ConsoleAppender appends log events to System.out or System.err ● FileAppender appends log events to a file ● RollingFileAppender extends FileAppender to backup the log files when they reach a certain size ● DailyRollingFileAppender extends FileAppender so that the underlying file is rolled over at a user chosen frequency ● SMTPAppender sends an when a specific logging event occurs ● JMSAppender publishes log events to a JMS Topic ● JDBCAppender provides for sending log events to a database Layouts ● PatternLayout configurable string pattern in a printf C function style ● XMLLayout appends log events as a series of log4j:event (log4j.dtd) ● HTMLLayout outputs events in a HTML table
43
The API 1: import org.slf4j.Logger; 2: import org.slf4j.LoggerFactory;
3: 4: public class Wombat { 5: 6: private final Logger logger = LoggerFactory.getLogger(Wombat.class); 7: Integer t; 8: Integer oldT; 9: 10: public void setTemperature(Integer temperature) { 11: 12: oldT = t; 13: t = temperature; 14: 15: logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT); 16: 17: if(temperature.intValue() > 50) { 18: logger.info("Temperature has risen above 50 degrees."); 19: } 20: } 21: }
44
SLF4J & Logback logback的前世今生
slf4j由log4j作者Ceki开发,逐步取代apahce commons logging。 logback由log4j作者Ceki开发,逐步取代log4j。
45
logback相比较log4j的优势 slf4j支持参数化
logger.error(“帐号ID:{}不存在”, userId); 告别了if(logger.isDebugEnable()) 时代 另外logback的整体性能比log4j也较佳,hibernate等项目已经采用了slf4j。
46
SLF4J and Logback : Dream Dates!
Logback implements SLF4J natively No computational and memory overhead Fully compliant to SLF4J Faster they say! 10 times!! Smaller Blue Print Core, classic and access modules
47
Why Logback Conditional Processing Good For Dev/Prod switch
Is It Worth A Use?
48
Why Logback Stack Traces Pointing jar files
49
logback.xml ConsoleAppender RollingFileAppender
rollover daily or whenever the file size reaches 100MB
52
Parameterized logging
inefficient syle logger.debug("Hello "+name); old style: if(logger.isDebugEnabled()) { } new style: logger.debug("Hello {}", name); In Java, any string parameter passed to a method is constructed before the method is called. While it make take 2 nanoseconds to evaluate that a logger is disabled for the DEBUG level when logger.debug() is invoked, it may take on “average” over 100 nanosecond to build the string “Hello”+ name. Thus, if you are concerned about performance, you might want to use conditional logging, or the much more convenient new style called parameterized logging introduced in SLF4J.
53
SiftingAppender or the appender-making appender
Sift logging according to runtime attributes E.g. separate logs according to user sessions, so that the log file generated by every user go into distinct log files, one log file per user. Works with any appender, not just FileAppender
54
SiftingAppender (continued)
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"> <discriminator> <Key>userid</Key> <DefaultValue>unknown</DefaultValue> </discriminator> <sift> <appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender"> <File>${userid}.log</File>s <Append>false</Append> <layout> <Pattern>%d %level %mdc %logger - %msg%n</Pattern> </layout> </appender> </sift>
55
Mapped Diagnostic Context(MDC)
线程映射表 日志框架维护的 map,日志框架通过提供了的键值对向其中插入日志信息。 映射诊断环境(Mapped Diagnostic Context) Logback的设计目标之一是审查和调试复杂的分布式应用程序。真实世界的多数分布式系统需要同时处理多个客户端。在一个典型的多线程方式实现的分布式系统里,不同的线程处理不同的客户端。区分不同客户端的记录输出的一个可行的但不好的方法是为每个客户端都创建新的、独立的logger。这种技术使logger的数量增多且大大增加了管理开销。 一个轻量的技术是为客户端的每个记录请求添加唯一戳(uniquely stamp)Logback在SLJ4J里使用了这种技术的一种变体:映射诊断环境(MDC) 为了给每个请求添加唯一戳,用户把环境(context)信息放进MDContext)
56
MDC MDC : Map Diagnostic Context
Helps to uniquely stamp requests Similar to NDC : Nested Diagnostic Context Correlating the logs effectively The MDC manages contextual information on a per thread basis(and its children) @Override public void processMsg(EmsMessage emsMessage) { EopLogBean msg = (EopLogBean) emsMessage.getMsg(); MDC.put(“userid", getActionFromTxid(msg.getTrxid())); log.info(msg.toString()); }
57
MDC Use Case: User Based Logging
public class UserServletFilter implements Filter { private final String USER_KEY = "username"; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; Principal principal = req.getUserPrincipal(); if (principal != null) { String username = principal.getName(); MDC.put(USER_KEY, username); } try { chain.doFilter(request, response); } finally { MDC.remove(USER_KEY);
58
MDC Use Case: User Based Logging
<appender name="CONSOLE“ class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%-4r [%thread] %-5level C:%X{username} - %msg%n</Pattern> </layout> </appender>
59
MDC Use Case: InsertingServletFilter
%X{req.remoteHost} %X{req.requestURI}%n%d - %m%n
60
Package versions in stack traces
java.lang.NullPointerException at com.xyz.Wombat(Wombat.java:57) ~[wombat-1.3.jar:1.3] at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native) ~[na:1.5.0_06] at java.lang.reflect.Method.invoke(Method.java:585) ~[na:1.5.0_06] at junit.runners.TestMethod.invoke(TestMethod.java:59) [junit-4.4.jar:na] etc..
61
JAVA String
62
String
63
StringUtils 空白: defaultIfBlank defaultIfEmpty defaultString deleteWhitespace normalizeSpace trim 判断: isAllLowerCase isAlpha isAlphanumeric isAlphanumericSpace isAlphaSpace isAsciiPrintable isNumeric isNumericSpace isWhitespace isBlank isEmpty isNotBlank isNotEmpty 合分: join split 结束: endsWith endsWithAny endsWithIgnoreCase 比较: difference equals equalsIgnoreCase getCommonPrefix getLevenshteinDistance overlay 查找: indexOf indexOfAny indexOfAnyBut indexOfDifference indexOfIgnoreCase lastIndexOf lastIndexOfAny lastIndexOfIgnoreCase lastOrdinalIndexOf ordinalIndexOf 删除: remove removeEnd removeEndIgnoreCase removeStart removeStartIgnoreCase 替换: replace replaceChars replaceEach replaceEachRepeatedly replaceOnce 反转: reverse reverseDelimited 子串: countMatches left mid right substring… 补充: leftPad repeat rightPad 大小写: capitalize lowerCase uncapitalize upperCase swapCase 缩略: abbreviate abbreviateMiddle 补充: center 裁剪: chomp chop strip… 包含:contains containsAny containsIgnoreCase containsNone containsOnly containsWhitespace
64
Guava Splitter JDK has splitter ‣ regular expression
‣ result as an array ‣ its way of handling empty pieces (which is very strange) Mini-puzzler ",a,,b,".split(",") returns... (a) "","a","","b","" (b) null,"a",null,"b",null (c) "a",null,"b" (d) "a","b" (e) None of the above
65
Splitter Breaks strings into substrings
by recognizing a separator (delimiter), one of: a single character: Splitter.on('\n') a literal string: Splitter.on(", ") a regex: Splitter.onPattern(",\\s*") any CharMatcher (remember that?) or using a fixed substring length Splitter.fixedLength(8) Iterable<String> pieces = Splitter.on(',').split("trivial,example") returns "trivial" and "example" in order.
66
The default behavior is simplistic:
//yields [" foo", " ", "bar", " quux", ""] Splitter.on(',').split(" foo, ,bar, quux,"); If you want extra features, ask for them! //yields ["foo", "bar", "quux"] Splitter.on(',') .trimResults() .omitEmptyStrings() .split(" foo, ,bar, quux,");
67
Guava Joiner Bizarrely Missing From The JDK Class Libraries:
joining pieces of text with a separator. String s = Joiner.on(", ").join(episodesOnDisc); Joiner is configurable: StringBuilder sb = ...; Joiner.on("|").skipNulls().appendTo(sb, attrs); It can even handle maps: static final MapJoiner MAP_JOINER = Joiner.on("; ") .useForNull("NODATA") .withKeyValueSeparator(":");
68
String到基本数据类型的转换 public static int parseInt(String s, int radix) throws NumberFormatException public static int parseInt(String s) public static byte parseByte(String s) public static short parseShort(String s) public static long parseLong(String s) public static float parseFloat(String s) public static double parseDouble(String s)
69
对象的字符串表示方法 Object类 public String toString() String类
public static String valueOf(char c) public static String valueOf(int i) public static String valueOf(long l) public static String valueOf(float f) public static String valueOf(double d)
70
BASE64 01 import static javax.xml.bind.DatatypeConverter.parseBase64Binary; 02 import static javax.xml.bind.DatatypeConverter.printBase64Binary; 03 05 public void testBase64() { 06 String s1 = "我是黄进兵!"; 07 String base64 = printBase64Binary(s1.getBytes(UTF_8)); 08 assertEquals("5oiR5piv6buE6L+b5YW1IQ==", base64); 09 byte[] bytes = parseBase64Binary(base64); 10 String s2 = new String(bytes, UTF_8); 11 assertEquals(s1, s2); 12 }
71
JAVA IO
72
Java Characters A Java character has two bytes
Java supports Unicode character set standard ASCII Java uses UTF-16 encoding Other unicode encodings: UTF-8 UTF-16 Other non-unicode encodings Windows-1256
73
Stream Concept
74
Java I/O Classes Text I/O Binary I/O
Stream of characters (Unicode format) Support provided by Reader and Writer Binary I/O Stream of bytes (raw format) Support provided by InputStream and OutputStream An InputStream reads raw octet (8 bit) data (byte). An InputStreamReader then will transform data from some encoding into UTF-16. If "a你们" is encoded as UTF-8 on disk, it will be the byte sequence 61 E4 BD A0 E4 BB AC. When you pass theInputStream to InputStreamReader with the UTF-8 encoding, it will be read as the char sequence0061 4F60 4EEC.
75
Reader和InputStream区别
Reader和InputStream分别是I/O库提供的两套平行独立的等级机构 InputStream、OutputStream是用来处理8位元的流,Reader、Writer是用来处理16位元的流。 InputStream、OutputStream是用来处理8位元的流,Reader、Writer是用来处理16位元的流。所以在处理中文的时候需要用Reader和Writer。 InputStreamReader、OutputStreamWriter负责进行InputStream到Reader的适配和由OutputStream到Writer的适配。 int copy(InputStream input, OutputStream output) void copy(InputStream input, Writer output, String encoding) void copy(Reader input, OutputStream output, String encoding) int copy(Reader input, Writer output)
76
Reader <-> InputStream Writer <->WriterOutputStream
Reader->InputStream commons-io :ReaderInputStream Writer->OutputStream commons-io :WriterOutputStream InputStream->Reader jdk:InputStreamReader OutputStream->Writer jdk:OutputStreamWriter InputStream->OutputStream? Reader->Writer?
77
Closeable Reader何时关闭? Writer何时关闭? InputStream 何时关闭? OutputStream何时关闭?
78
FileUtils
79
Guava common.io Typically: InputSupplier<InputStream>, OutputSupplier<Writer>,etc. 2 key interfaces public interface InputSupplier<T> { T getInput() throws IOException; } public interface OutputSupplier<T> { T getOutput() throws IOException; This lets all Guava’s utilities be useful for many kinds of I/O. Terminology ‣ byte stream means "InputStream or OutputStream" ByteStreams utilities class ‣ char stream means "Reader orWriter." CharStreams utilities class
80
common.io: ByteStreams
byte[] toByteArray(InputStream) byte[] toByteArray(InputSupplier) void readFully(InputStream, byte[]) void write(byte[], OutputSupplier) long copy(InputStream, OutputStream) long copy(InputSupplier, OutputSupplier) long length(InputSupplier) boolean equal(InputSupplier, InputSupplier) InputSupplier slice(InputSupplier, long, long) InputSupplier join(InputSupplier...) CharStreams is similar, but deals in Reader, Writer, String and CharSequence (often requiring you to specify a Charset).
81
common.io: Files The Files class works one level higher than ByteStreams and CharStreams, and has a few other tricks. byte[] toByteArray(File) String toString(File, Charset) void write(byte[], File) void write(CharSequence, File, Charset) long copy(File, File) long copy(InputSupplier, File) long copy(File, OutputSupplier) long copy(File, Charset, Appendable) long move(File, File) boolean equal(File, File) List<String> readLines(File, Charset)
82
More about Files File createTempDir()
void deleteDirectoryContents(File) void deleteRecursively(File) long getChecksum(File,Checksum) byte[] getDigest(File,MessageDigest) String readFirstLine(File,Charset) List<String> readLines(File,Charset) T readLines(File,Charset, LineProcessor<T>) String toString(File,Charset)
83
Flushables and Closeablesb
Flushables.flushQuietly(Flushable flushable) Flushables.flush( Flushable flushable, boolean swallowIOException) throws IOException Closeables.closeQuietly(Closeable closeable) Closeables.close( Closeable closeable, Very usefull in finally blocks (avoid nesting try/catch)
84
Java Collections
85
Java array and collections
86
JAVA Collections
87
Java Collection Interfaces
4种基本形式,前三种的父接口是Collection。 1:List 关注对象的索引列表 2:Set 关注对象的唯一性 3:Queue 关注对象被处理时的顺序 4:Map 关注映射和键值的唯一性
90
Collection Utilities
91
List具体实现类
92
Map具体实现类
93
Set具体实现类
94
Queue具体实现类
96
Multiset
97
Multimap ListMultimap & SetMultimap
Map<String, List<T>> & Map<String, Set<T>> Operations: put(K, V), putAll(K, Iterable<V>), remove(K, V), removeAll(K, Iterable<V>), replaceValues(K, Iterable<V>)
98
Multimap Implementations
99
BiMap BiMap<K, V> is Map<K,V> with unique values
Operations: all Map, inverse(), values() as Set Throws an IllegalArgumentException if you attempt to map a key to an already-present value
100
BiMap Implementations
101
Table
102
Copy! or make it immutable... Lists.newArrayList()
Lists.newLinkedList() Sets.newHashSet() Sets.newLinkedHashSet() Sets.newTreeSet() or make it immutable... ImmutableList.copyOf() ImmutableSet.copyOf()
103
不同集合类型有不同的时间复杂度 Operation Obtain size Constant Add element Log
ArrayList LinkedList HashSet TreeSet Obtain size Constant Add element Log Remove given element Linear Remove by index – Get element by index Find out if contains Depending on the size, different types of collections may behave better that others
104
how to choose correct java collection class (When to use which collection in java )
105
泛型练习 泛型改造MyStack 增加方法: pushAll 增加方法: popAll @Test
public void testStack() { MyStack<Number> numberStack = new MyStack<Number>(); Collection<Integer> integers = new ArrayList<Integer>(); integers.add(1); numberStack.pushAll(integers); Collection<Object> objects = new ArrayList<Object>(); numberStack.popAll(objects); }
106
The Get and Put Principle
public static <T> void copy(List<? super T> dest, List<? extends T> src) use an extends wildcard when you only get values out of a structure, use a super wildcard when you only put values into a structure, and don't use a wildcard when you both get and put. A Mnemonic for Wildcard Usage • PECS—Producer extends, Consumer super – use Foo<? extends T> for a T producer – use Foo<? super T> for a T consumer • Only applies to input parameters – Don’t use wildcard types as return types
107
Misc. Tuples The of-Operator ULong, UInt, UShort
108
Java Reflections
109
Metadata Java stores metadata in classes
- Metadata for a class: Metadata for a constructor: Metadata for a field: Metadata for a method: java.lang.Class java.lang.reflect.Constructor java.lang.reflect.Field java.lang.reflect.Method Two ways to access a Class object for a class: Class c1 = Class.forName(“java.util.Properties”); Object obj = ...; Class c2 = obj.getClass(); Reflection classes are inter-dependent n - Examples are shown on the next slide
110
Examples of inter-relatedness of reflection classes
class Class { Constructor[] Field Field[] Method[] getConstructors(); getDeclaredField(String name); getDeclaredFields(); getDeclaredMethods(); ... } class Field { Class getType(); class Method { Class[] getParameterTypes(); Class ... getReturnType(); }
111
Metadata for primitive types and arrays
Java associates a Class instance with each primitive type: Class c1 = int.class; Class c2 = boolean.class; Class c3 = void.class; Might be returned by Method.getReturnType() Use Class.forName() to access the Class object for an array Class c4 c5 c6 c7 = byte.class; // byte Class.forName(“[B”); // byte[] Class.forName(“[[B”); // byte[][] Class.forName(“[Ljava.util.Properties”); Encoding scheme used by Class.forName() B à byte; C à char; D à double; F à float; I à int; J à long; Lclass-name à class-name[]; S à short; Z à boolean Use as many “[”s as there are dimensions in the array
112
Miscellaneous Class methods
Here are some useful methods defined in Class class Class { public String getName(); // fully-qualified name public boolean isArray(); public boolean isInterface(); public boolean isPrimitive(); public Class getComponentType(); // only for arrays ... }
113
Invoking a default constructor
Use Class.newInstance() to call the default constructor Example: abstract class Foo { public static Foo create() throws Exception { String className = System.getProperty( “foo.implementation.class”, “com.example.myproject.FooImpl”); Class c = Class.forName(className); return (Foo)c.newInstance(); } abstract void op1(...); abstract void op2(...); ... Foo obj = Foo.create(); obj.op1(...);
114
A plug-in architecture
Use a properties file to store a mapping for plugin name à class name Many tools support plugins: Ant, Maven, Eclipse, … abstract class Plugin { abstract void op1(...); } abstract class PluginManager { public static Plugin load(String name) throws Exception { String className = props.getProperty(name); Class c = Class.forName(className); return (Plugin)c.newInstance(); ... Plugin obj = PluginManager.load(“...”);
115
Invoking a non-default constructor
Slightly more complex than invoking the default constructor: -Use Class.getConstructor(Class[] parameterTypes) -Then call Constructor.newInstance(Object[] parameters) abstract class PluginManager { public static Plugin load(String name) throws Exception { String className = props.getProperty(name); Class c = Class.forName(className); Constructor cons = c.getConstructor( new Class[]{String.class, String.class}); return (Plugin)cons.newInstance( new Object[]{“x”, “y”}); } ... Plugin obj = PluginManager.load(“...”);
116
Passing primitive types as parameters
If you want to pass a primitive type as a parameter: Wrap the primitive value in an object wrapper Then use the object wrapper as the parameter Object wrappers for primitive types: boolean byte char int ... à - java.lang.Boolean java.lang.Byte java.lang.Character java.lang.Integer
117
Invoking a method Broadly similar to invoking a non-default constructor: Use Class.getMethod(String name, Class[]parameterTypes) Then call Method.invoke(Object target, Object[] parameters) Object obj = ... Class c = obj.getClass(); Method m = c.getMethod(“doWork”, new Class[]{String.class, String.class}); Object result= m.invoke(obj, new Object[]{“x”,“y”});
118
Looking up methods The API for looking up methods is fragmented:
You can lookup a public method in a class or its ancestor classes Or, lookup a public or non-public method declared in the specified class - A better name would have been getPublicMethod() class Class { public Method getMethod(String name, Class[] parameterTypes); public Method[] getMethods(); public Method getDeclaredMethod(String name, public Method[] getDeclaredMethods(); ... }
119
Finding an inherited method
This code searches up a class hierarchy for a method -Works for both public and non-public methods Method findMethod(Class cls, String methodName, Class[] paramTypes) { Method method = null; while (cls != null) { try { method = cls.getDeclaredMethod(methodName, paramTypes); break; } catch (NoSuchMethodException ex) { cls = cls.getSuperclass(); } return method;
120
Accessing a field There are two ways to access a field:
By invoking get- and set-style methods (if the class defines them) By using the code shown below Object obj = ... Class c = obj.getClass(); Field f = c.getField(“firstName”); f.set(obj, “John”); Object value = f.get(obj); -
121
Looking up fields The API for looking up fields is fragmented:
You can lookup a public field in a class or its ancestor classes Or, lookup a public or non-public field declared in the specified class - A better name would have been getPublicField() getField(String name); getFields(); getDeclaredField(String name); getDeclaredFields(); would have been getPublicField() class Class { public Field public Field[] ... }
122
Finding an inherited field
This code searches up a class hierarchy for a field Works for both public and non-public fields - Field findField(Class cls, String fieldName) { Field field = null; while (cls != null) { try { field = cls.getDeclaredField(fieldName); break; } catch (NoSuchFieldException ex) { cls = cls.getSuperclass(); } return field;
123
Java modifiers Java defines 11 modifiers:
abstract, final, native, private, protected, public, static, strictfp, synchronized, transient and volatile - Some of the modifiers can be applied to a class, method or field: n - Set of modifiers is represented as bit-fields in an integer Access set of modifiers by calling int getModifiers() Useful static methods on java.lang.reflect.Modifier: n static ... boolean isAbstract(int modifier); isFinal(int modifier); isNative(int modifier); isPrivate(int modifier);
124
Accessing non-public fields and methods
Both Field and Method define the following methods (inherited from java.lang.reflect.AccessibleObject): boolean isAccessible(); void setAccessible(boolean flag); static void setAccessible(AccessibleObject[] array, boolean flag); Better terminology might have been “SuppressSecurityChecks” instead of “Accessible” Example of use: if (!Modifier.isPublic(field.getModifiers()) { field.setAccessible(true); n Hibernate uses this technique so it can serialize non-public
125
JOOR A fluent reflection API for Java
jOOR stands for Java Object Oriented Reflection. It is a simple wrapper for the java.lang.reflect package. String world = on("java.lang.String") // Like Class.forName() .create("Hello World") // Call the most specific matching constructor .call("substring", 6) // Call the most specific matching substring() method .call("toString") // Call toString() .get(); // Get the wrapped object, in this case a String
126
Performance // Method reflection with ReflectASM:
SomeClass someObject = ... MethodAccess access = MethodAccess.get(SomeClass.class); access.invoke(someObject, "setName", "Awesome McLovin"); String name = (String)access.invoke(someObject, "getName");
127
Comparison with standard java.lang.reflect
Employee[] employees = on(department).call("getEmployees").get(); for (Employee employee : employees) { Street street = on(employee).call("getAddress").call("getStreet").get(); System.out.println(street); } jOOR code: try { Method m1 = department.getClass().getMethod("getEmployees"); Employee employees = (Employee[]) m1.invoke(department); for (Employee employee : employees) { Method m2 = employee.getClass().getMethod("getAddress"); Address address = (Address) m2.invoke(employee); Method m3 = address.getClass().getMethod("getStreet"); Street street = (Street) m3.invoke(address); System.out.println(street); } } // There are many checked exceptions that you are likely to ignore anyway catch (Exception ignore) { // ... or maybe just wrap in your preferred runtime exception: throw new RuntimeException(e); } The same example with normal reflection in Java:
128
JavaScript Object Notation
129
Eclipse json editor { hotelList:[
{name:"Beijing",address:"Haidian Road NO:1",price:110.0}, {name:"Beijing",address:"Haidian Road NO:2",price:120.0}, {name:"Beijing",address:"Haidian Road NO:3",price:130.0}, {name:"Beijing",address:"Haidian Road NO:4",price:140.0}, {name:"Beijing",address:"Haidian Road NO:5",price:150.0}, {name:"Beijing",address:"Haidian Road NO:6",price:160.0}, {name:"Beijing",address:"Haidian Road NO:7",price:170.0} ], timeStamp:"Wed Oct 08 10:25:10 CST 2008" }
130
JSON Form View
131
What is JSON? • Lightweight data-interchange format • Simple format
> Compared to XML • Simple format > Easy for humans to read and write > Easy for machines to parse and generate • JSON is a text format > Programming language independent > Uses conventions that are familiar to programmers of the C- family of languages, including C, C++, C#, Java, JavaScript, Perl, Python
132
Why Use JSON over XML • Lighter and faster than XML as on-the-wire data format • JSON objects are typed while XML data is typeless > JSON types: string, number, array, boolean, > XML data are all string • Native data form for JavaScript code > Data is readily accessible as JSON objects in your JavaScript code vs. XML data needed to be parsed and assigned to variables through tedious DOM APIs > Retrieving values is as easy as reading from an object property in your JavaScript code
133
JSON Tools for Java Developer
• Parser > Parse JSON text files and convert these to a Java model • Renderer > Render a Java representation into text • Serializer > Serialize plain POJO clusters to a JSON representation • Validator > Validate the contents of a JSON file using a JSON schema
134
Alibaba FastJSON 基本序列化 反序列化 Object o = ...;
String text = JSON.toJSONString(o); 反序列化 String text = ...; // {"r":255,"g":0,"b":0,"alpha":255} Color color = JSON.parseObject(text, Color.class);
135
JSON Schema { "$schema" : "http://json-schema.org/draft-03/schema#",
"id" : " "type" : "object", "properties" : { "type" : { "type" : ["string", "array"], "items" : { "type" : ["string", {"$ref" : "#"}] }, "uniqueItems" : true, "default" : "any" "additionalProperties" : {"$ref" : "#"}, "default" : {}
136
XML tools XMLTag tag = XMLDoc.newDocument(false) .addDefaultNamespace(" .addNamespace("wicket", " .addRoot("html") .addTag("wicket:border") .gotoRoot().addTag("head") .addNamespace("other", " .gotoRoot().addTag("other:foo"); System.out.println(tag.toString());
137
XML tools Features Create new XML documents from external sources or new document from scrash Manage namespaces Manipulating nodes (add, remove, rename) Manipulating data (add, remove text or CDATA) Navigate into the document with shortcuts and XPath (note: XPath supports namespaces) Tranform an XMlDoc instance to a String or a Document Validate your document against schemas Executin callbacks on a hierarchy Remove all namspaces (namespace ignoring) ... and a lot of other features !
138
jOOX-Java Object Oriented XML
// Find the order at index for and add an element "paid" $(document).find("orders").children().eq(4).append("<paid>true</paid>"); // Find those orders that are paid and flag them as "settled" $(document).find("orders").children().find("paid").after("<settled>true</settled>"); // Add a complex element $(document).find("orders").append( $("order", $("date", " "), $("amount", "155"), $("paid", "false"), $("settled", "false")).attr("id", "13");
139
JOOQ SELECT * FROM BOOK WHERE PUBLISHED_IN = 2011 ORDER BY TITLE
create.selectFrom(BOOK) .where(PUBLISHED_IN.equal(2011)) .orderBy(TITLE) SELECT FIRST_NAME, LAST_NAME, COUNT(*) FROM AUTHOR JOIN BOOK ON AUTHOR.ID = BOOK.AUTHOR_ID WHERE LANGUAGE = 'DE' AND PUBLISHED > ' ' GROUP BY FIRST_NAME, LAST_NAME HAVING COUNT(*) > 5 ORDER BY LAST_NAME ASC NULLS FIRST LIMIT 2 OFFSET 1 FOR UPDATE OF FIRST_NAME, LAST_NAME create.select(FIRST_NAME, LAST_NAME, count()) .from(AUTHOR) .join(BOOK) .on(Author.ID.equal(Book.AUTHOR_ID)) .where(LANGUAGE.equal("DE")) .and(PUBLISHED.greaterThan(parseDate(" "))) .groupBy(FIRST_NAME, LAST_NAME) .having(count().greaterThan(5)) .orderBy(LAST_NAME.asc() .nullsFirst()) .limit(2).offset(1) .forUpdate() .of(FIRST_NAME, LAST_NAME)
140
JOOQ + H2 01 import org.jooq.util.h2.H2Factory; 02 import cn.bingoo.h2.domain.Tables; 03 import cn.bingoo.h2.domain.tables.records.VouchercardRecord; 04 06 public void testJooq() throws Exception { 07 DriverManager.registerDriver(new org.h2.Driver()); 08 Connection conn = DriverManager.getConnection("jdbc:h2:~/bingoo-handy", "sa", ""); 09 Factory factory = new H2Factory(conn); 10 11 VouchercardRecord newRecord = factory.newRecord(Tables.VOUCHERCARD); 12 newRecord.setCode("mycode"); newRecord.setPass("mypass"); newRecord.setHmac("mymac"); 13 newRecord.store(); 14 15 VouchercardRecord fetchOne = factory.selectFrom(Tables.VOUCHERCARD) 16 .where(Tables.VOUCHERCARD.CODE.equal("mycode")).fetchOne(); 17 18 assertEquals(newRecord, fetchOne); 19 20 conn.close(); 21 }
141
Regular Expression正则表达式
文本处理的利器(grep, perl, ruby, lua内嵌) Perl,ruby,javascript 写法 /[a-z]+/ Eg. name = “Dave”; name =~ /[a-z]/; 找到ave JDK1.4 java.util.regex 一些简单例子: [a-z] 匹配一个或多个小写字母 abc exactly this sequence of three letters [abc] any one of the letters a, b, or c [^abc] any character except one of the letters a, b, or c (immediately within an open bracket, ^ means “not,” but anywhere else it just means the character ^) [a-z] any one character from a through z, inclusive [a-zA-Z0-9] any one letter or digit abc|xyz match either abc or xyz [A-Za-z]+[0-9] match one or more letters immediately followed by one digit
142
REGEX Groups and Ranges(分组和范围) Character Classes(字符分类)
. Any character except new line (\n) (a|b) a or b (...) Group (?:...) Passive (non-capturing) group [abc] Range (a or b or c) [^abc] Not a or b or c [a-q] Letter from a to q [A-Q] Upper case letter from A to Q [0-7] Digit from 0 to 7 \n nth group/subpattern Ranges are inclusive. Regular Expressions Anchors(锚定符) ^ Start of string, or start of line in multi-line pattern \A Start of string $ End of string, or end of line in multi-line pattern \Z End of string \b Word boundary \B Not word boundary \< Start of word \> End of word Character Classes(字符分类) \c Control character 控制字符 \s White space 空白字符 \S Not white space 非空白 \d Digit 数字 \D Not digit 非数字 \w Word 单词 \W Not word 非单词 \x Hexadecimal digit 16进制 \O Octal digit 8进制 Quantifiers(限定符) X* 0 or more X+ 1 or more X? 0 or 1 X{3} Exactly 3 X{3,} 3 or more X{3,5} 3, 4 or 5 Add a ? to a quantifier to make it ungreedy.
143
限定符类型Types of quantifiers
A greedy quantifier will match as much as it can, and back off if it needs to We’ll do examples in a moment A reluctant quantifier will match as little as possible, then take more if it needs to You make a quantifier reluctant by appending a ?: X?? X*? X+? X{n}? X{n,}? X{n,m}? A possessive quantifier will match as much as it can, and never let go You make a quantifier possessive by appending a +: X?+ X*+ X X{n}+ X{n,}+ X{n,m}+
144
限定符示例 Suppose your text is aardvark
Using the pattern a*ardvark (a* is greedy): The a* will first match aa, but then ardvark won’t match The a* then “backs off” and matches only a single a, allowing the rest of the pattern (ardvark) to succeed Using the pattern a*?ardvark (a*? is reluctant): The a*? will first match zero characters (the null string), but then ardvark won’t match The a*? then extends and matches the first a, allowing the rest of the pattern (ardvark) to succeed Using the pattern a*+ardvark (a*+ is possessive): The a*+ will match the aa, and will not back off, so ardvark never matches and the pattern match fails
145
JAVA中的Regex 01 import java.util.regex.Matcher; 02 import java.util.regex.Pattern; 03 05 public void testRegex() { 06 Pattern p = Pattern.compile(“[a-z]+”); 07 String text = “Hello world”; 08 Matcher m = p.matcher(text); 09 assertTrue(m.find()); 10 assertEquals("ello", text.substring(m.start(), m.end())); 11 assertTrue(m.find()); 12 assertEquals("world", text.substring(m.start(), m.end())); 13 assertFalse(m.find()); 14 }
146
分组Capturing groups In regex, parentheses are used for grouping, but they also capture (keep for later use) anything matched by that part of the pattern Example: ([a-zA-Z]*)([0-9]*) matches any number of letters followed by any number of digits If the match succeeds, \1 holds the matched letters and \2 holds the matched digits In addition, \0 holds everything matched by the entire pattern Capturing groups are numbered by counting their opening parentheses from left to right: ( ( A ) ( B ( C ) ) ) \0 = \1 = ((A)(B(C))), \2 = (A), \3 = (B(C)), \4 = (C) Example: ([a-zA-Z])\1 will match a double letter, such as letter
147
JAVA中的regex group和replace
02 public void testBasicGroup() { 03 Pattern p = Pattern.compile("((\\d+)\\s+(boys|girls))"); 04 05 String text = "There are total 15 boys and 12 girls in class 1."; 06 Matcher m = p.matcher(text); 07 assertTrue(m.find()); 08 assertEquals("15 boys", m.group(1)); 09 assertEquals("15", m.group(2)); 10 assertEquals("boys", m.group(3)); 11 assertTrue(m.find()); 12 assertEquals("12 girls", m.group(1)); 13 assertEquals("12", m.group(2)); 14 assertEquals("girls", m.group(3)); 15 assertFalse(m.find()); 16 } 17 19 public void testReplace() { 20 String text = "There are total 15 boys and 12 girls in class 1."; 21 String replacedText = text.replaceAll("(\\d+)\\s+boys", "$1 men"); 22 assertEquals("There are total 15 men and 12 girls in class 1.", replacedText); 23 }
148
String类中的正则 public boolean matches(String regex)
public String replaceFirst(String regex, String replacement) public String replaceAll(String regex, String replacement) public String[ ] split(String regex) public String[ ] split(String regex, int limit) If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible
149
Matcher类中的方法 If m is a matcher, then
m.replaceFirst(replacement) returns a new String where the first substring matched by the pattern has been replaced by replacement m.replaceAll(replacement) returns a new String where every substring matched by the pattern has been replaced by replacement m.find(startIndex) looks for the next pattern match, starting at the specified index m.reset() resets this matcher m.reset(newText) resets this matcher and gives it new text to examine (which may be a String, StringBuffer, or CharBuffer)
150
REGEX cont. Special Characters \n New line \r Carriage return \t Tab
\v Vertical tab \f Form feed \xxx Octal character xxx \xhh Hex character hh Pattern Modifiers g Global match i Case-insensitive m Multiple lines s Treat string as single line x Allow comments and white space in pattern e Evaluate replacement U Ungreedy pattern String Replacement(有的实现使用\替代$) $n nth non-passive group $2 "xyz" in /^(abc(xyz))$/ $1 "xyz" in /^(?:abc)(xyz)$/ $` Before matched string $' After matched string $+ Last matched string $& Entire matched string Assertions ?= Lookahead assertion ?! Negative lookahead ?<= Lookbehind assertion ?!= or ?<! Negative lookbehind ?> Once-only Subexpression ?() Condition [if then] ?()| Condition [if then else] ?# Comment
151
RegexBuddy 练习 1) 匹配字母,数字和减号 Letters, digits and hyphens
2) 匹配日期 yyyy-mm-dd 3) jpg, gif或png图片文件名 4) 地址 5) Html tags 6) 至少包括一个大写字母、小写字母和数字(密码强度) [a-zA-Z0-9]+ \d{2,4}-\d{1,2}-\d{1,2} [^\s]+(?=\.(jpg|gif|png)) (?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,15} <(/?[^\>]+)>
152
Scalable language
153
Pragmatic 2003 Production Statically typed Seamless Java
runs on the JVM Martin Odersky Since 2003 Seamless Java interoperability Production ready Statically typed Hybrid
154
“I can honestly say if someone had shown me the Programming Scala book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy.“ James Strachan, creator of Groovy
155
“If I were to pick a language to use today other than Java, it would be Scala.”
James Gosling
156
Who uses Scala already
157
一切值都是对象的实例 • JVM中的原生类型是对象的实例 函数也是值,从而也是对象的实例
123.toByte "1".toInt true.toString 函数也是值,从而也是对象的实例 val compare = (x: Int, y: Int) => x > y compare(1, 2) // result: Boolean = false Java的static方法和域再没有存在的理由,因为它们的所有者 也必须是对象的实例(值),所以有了Scala中的单例object object Dog { val whatever = "dog" // static field in Java } class Dog { def callWhatever = Dog.whatever
158
函数作为值 • 可以当作参数传递 不管它是实例的方法 还是匿名子句 没有了sta&c域,一切函数,包括object的方法调用现在都是
val compare = (x: Int, y: Int) => x > y list sortWith compare 不管它是实例的方法 class AComparator { def compare(x: Int, y: Int) = x > y } list sortWith (new AComparator).compare 还是匿名子句 object annonymous extends scala.Function2[Int, Int, Boolean] { override def apply(x: Int, y: Int) = x > y list sortWith annonymous 没有了sta&c域,一切函数,包括object的方法调用现在都是 值(实例)的方法
159
• • 只有一个参数或零个参数的方法在调用时可以省略”.”和”()” 参数也可以是一系列操作 {...} 更多的符号需要用作方法名
一切操作都是函数调用(1) 只有一个参数或零个参数的方法在调用时可以省略”.”和”()” 1.+(1) 1.>(0) 1 > 0 (1 > 0).&(2 > 1) (1 > 0) & > 1 stack.push(10) stack push 10 stack.pop stack pop 参数也可以是一系列操作 {...} stack push { • val a + a = 1 b = 2 b } 更多的符号需要用作方法名 def = println("noop") def √(x: Double) = Math.sqrt(x) val Π = Math.Pi val r = √(9*Π) ‘<’, ‘>’更适合作方法名,所以用’[’和‘]’来表示类型参数 •
160
一切操作都是函数调用(2) • for语句是函数调用 更多的例子 额外的好处:自左向右顺序书写语句 println(i) i + 10
for (i <- List(1, 2)) { println(i) } List(1, 2) foreach {i => println(i)} for (i <- List(1, 2)) yield { i List(1, 2) map {i => i } 更多的例子 // synchronized is function call instead of keyword def check = synchronized { // isInstanceOf is function call instead of keyword 100.isInstanceOf[String] 额外的好处:自左向右顺序书写语句 stack.pop.asInstanceOf[Int] // (Integer) stack.pop() in Java
161
一切操作都返回值 • 默认返回最后一条语句的值,也可以用return显式返回 val r1 = { // return 3
val a = 1 val b = 2 a b } val r2 = if (true) else 2 val r3 = // return (): Unit for (i <- List(1, 2)) { println(i) val r4 = // return List(11, 12) for (i <- List(1, 2)) yield { i val r5 = // return java.io.File try { val f = new File("afile") f } catch { case ex: IOException => null
162
Higher Level // Scala val hasUpperCase = name.exists(_.isUpperCase)
// Java – Check if string has uppercase character boolean hasUpperCase = false; for(int i = 0; i < name.length(); i++) { if(Character.isUpperCase(name.charAt(i))) { hasUpperCase = true; break; } // Scala val hasUpperCase = name.exists(_.isUpperCase)
163
Declaring classes // Scala class Person( var name: String,
…concisely // Java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; public int getAge() { return age; public void setName(String name) { public void setAge(int age) { // Scala class Person( var name: String, var age: Int )
164
Java – working with Person
Scala – Pattern Matching Object x = new Person("Bill Clinton", 64); if(x instanceof Person) { Person p = (Person)x; System.out.println(„Person name: "+p.getName()); } else { System.out.println("Not a person"); } x = "Lukasz Kuczera"; System.out.println("hello "+p.getName()); } else if(x instanceof String) { String s = (String)x; if(s.equals("Bill Clinton")) System.out.println("Hello Bill"); else System.out.println("hello: "+s); } else System.out.println("err, ???"); var x: Any = Person("Lukasz", 28); x match { case Person(name, age) => println("Person name: "+name); case _ => println("Not a person") } x = "Lukasz Kuczera" println("Person name: "+name) case "Bill Clinton" => println("hello Bill") case s: String => println("hello "+s) case _ => "err, ???" Person name: Lukasz hello Lukasz Kuczera
165
Pattern matching …is concise // Scala reactions += {
// Java button.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseEntered(MouseEvent e) { System.out.println(“I see it!”); } public void mouseExited(MouseEvent e) { System.out.println(“Lost it.”); public void mouseClicked(MouseEvent e) { System.out.println(“Poked!”); // ...alternative - isinstanceof // Scala reactions += { case m: MouseEntered => println(“I see it!”) case m: MouseExited => println(“Lost it.”) case m: MouseClicked => println(“Poked!”) }
166
Working with arrays // Java // Scala public class Partition {
Person[] all; Person[] adults; Person[] minors; { ArrayList<Person> minorsList = new ArrayList<Person>(); ArrayList<Person> adultsList = new ArrayList<Person>(); for(int i=0; i<all.length; i++ ) { (all[i].age<18 ? adultsList: minorsList).add(all[i]); } minors = (Person[]) minorsList.toArray(); adults = (Person[]) adultsList.toArray(); // Scala val all: Array[Person] val (minors, adults) = all.partition(_.age<18)
167
Duck Typing class Duck { def quack = "呱...呱..." }
def doQuack(d: {def quack: String}) { println(d.quack) doQuack(new Duck)
168
Nice to know Scala: Java: Console.println(“Hello”) println(“Hello”)
val line = Console.readLine() val line = readLine() error(“Bad”) 1 + 1 1 .+(1) 1 == new Object 1 eq new Object """A\sregex""".r Java: System.out.println(“Hello”); BufferedReader r = new BufferedReader(new InputStreamRead(System.in) String line = r.readLine(); throw new RuntimeException(“Bad”) new Integer(1).toInt() + new Integer(1).toInt(); new Integer(1).equals(new Object()); new Integer(1) == new Object(); java.util.regex.Pattern.compile(“A\\sregex”);
169
“A little learning is a dangerous thing; drink deep, or taste not the Pierian spring: there shallow draughts intoxicate the brain, and drinking largely sobers us again.” Alexander Pope 学识浅薄是件危险的事情; 要么酣饮,不然就尝不到知识源泉的甘霖。 在那里浅斟薄饮使头脑醉昏, 大量畅饮会使我们清醒。 --亚历山大·蒲柏
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.