COMMON JAVA JAVA 数据结构与常用类库简介

169
COMMON JAVA JAVA 数数数数数数数数数数数 Bingoo

description

COMMON JAVA JAVA 数据结构与常用类库简介. Bingoo. JAVA 类加载. Java Classloading. Why do we care? 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 - PowerPoint PPT Presentation

Transcript of COMMON JAVA JAVA 数据结构与常用类库简介

Page 1: COMMON JAVA JAVA 数据结构与常用类库简介

COMMON JAVAJAVA 数据结构与常用类库简介

Bingoo

Page 2: COMMON JAVA JAVA 数据结构与常用类库简介

JAVA 类加载

Page 3: COMMON JAVA JAVA 数据结构与常用类库简介

Java Classloading• Why do we care?

– 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

Page 4: COMMON JAVA JAVA 数据结构与常用类库简介

Java Classloading

• So what is this 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

Page 5: COMMON JAVA JAVA 数据结构与常用类库简介

Java Classloading

Commandline Java App Tomcat (6)

Bootstrap classloader

Ext classloader

Application/ System

classloader

Application/ System

classloader

Common classloader

WAR 1classloader

WAR 2classloader

Loads the Application Jars from the classpath

Loads onlybootstrap.jar and tomcat-juli.jar

Loads Tomcat commons library jars

Loads jars in the webapp lib directory

Page 6: COMMON JAVA JAVA 数据结构与常用类库简介

自定义类加载器加载一个类的步骤 

Page 7: COMMON JAVA JAVA 数据结构与常用类库简介

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.

Page 8: COMMON JAVA JAVA 数据结构与常用类库简介

aopalliance-1.0.jarasm-3.3.jarasm-commons-3.3.jarasm-tree-3.3.jaraxis-1.4.jarbcprov-jdk16-1.45.jarcglib-nodep-2.2.jarcommons-beanutils-1.8.3.jarcommons-codec-1.5.jarcommons-collections-3.2.jarcommons-discovery-0.4.jarcommons-fileupload-1.2.2.jarcommons-httpclient-3.1.jarcommons-io-2.0.1.jarcommons-lang-2.1.jarcommons-logging-1.1.1.jarcommons-net-2.2.jarcommons-pool-1.6.jarcommons-ssh-1.5.1.jardom4j-1.6.1.jarems-consumer-0.0.1-SNAPSHOT.jarfastjson-1.1.17.jarfreemarker-2.3.18.jarguava-12.0.jarhadoop-core-0.20-append-r1056497.jar

hbase-0.90.4.jarhessian-3.1.6.jaribatis-sqlmap-2.3.4.726.M01.jarjavassist-3.11.0.GA.jarjline-0.9.94.jarjmockit-0.999.4.jarjsch-0.1.46.jarjsr305-1.3.9.jarjunit-4.8.2.jarkafka-0.7.0.jarLinkage-EcsCommon-0.0.1.jarlog4j-1.2.16.jarntfPlat-mailsend-0.0.1.jarntfplat-send-0.0.1.jarognl-3.0.4.jarPageSecurity-0.0.2.jarphw-all-0.1.0.jarProxyForEcsSms-1.0.jarscala-library-2.8.0.jarslf4j-api-1.6.2.jarslf4j-log4j12-1.6.2.jarsolr-solrj-3.4.0.jarspring-2.5.6.jarspring-beans-2.5.6.jarspring-context-2.5.6.jar

spring-context-support-2.5.6.jarspring-core-2.5.6.jarspring-web-2.5.6.jarspring-webmvc-2.5.6.jarspymemcached-2.8.0.jarstruts2-convention-plugin-2.3.1.2.jarstruts2-core-2.3.1.2.jarstruts2-json-plugin-2.3.1.2.jarwsdl4j-1.6.2.jarxerces-2.6.2.jarxwork-core-2.3.1.2.jarzkclient-0.1.jarzookeeper-3.3.3.jar

Page 9: COMMON JAVA JAVA 数据结构与常用类库简介

JAVA Exception

Page 10: COMMON JAVA JAVA 数据结构与常用类库简介
Page 11: COMMON JAVA JAVA 数据结构与常用类库简介

几种设计异常的最佳实践 (Best Practises for Designing the API)

• 选择 Checked 还是 Unchecked 的几个经典依据• Exception 的封装问题• 如无必要不要创建自己的 Exception• 不要用 Exception 来作流程控制• 不要轻易的忽略捕获的 Exception• 不要简单地捕获顶层的 Exception

Page 12: COMMON JAVA JAVA 数据结构与常用类库简介

三种”情景”导致异常的抛出• 编程错误导致 (Exception due Programming errors)

– 这种情景下,异常往往处于编程错误 ( 如:NullPointerException 或者 IllegalArgumentException), 这时异常一旦抛出,客户端将变得无能为力。

• 客户端代码错误导致 (Exception due client code errors)– 客户端试图调用 API 不允许的操作

• 资源失败导致 (Exception due to resource failures)– 如内存不足或网络连接失败导致出现异常等。这些异常的出现客户端可以采取相应的措施来恢复应用程序的继续运行。

Page 13: COMMON JAVA JAVA 数据结构与常用类库简介

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 blockEither 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

Page 14: COMMON JAVA JAVA 数据结构与常用类库简介

Checked or Unchecked exception

• 问自己一个问题,“如果这种异常一旦抛出,客户端会做怎样的补救 ?”– 如果客户端可以通过其他的方法恢复异常,那么这种异常就是 checked exception;– 如果客户端对出现的这种异常无能为力,那么这种异常就是 Unchecked exception;– 尽量使用 unchecked exception 来处理编程错误 ;譬如: NullPointerException ,

IllegalArgumentException 和 IllegalStateException

Page 15: COMMON JAVA JAVA 数据结构与常用类库简介

保护封装性 (Preserve encapsulation)

• 不要让你要抛出的 checked exception 升级到较高的层次。– 例如,不要让 SQLException 延伸到业务层。业务层并不需要 ( 不关心 ?)SQLException 。– 转变 SQLException 为另外一个 checked

exception ,如果客户端并不需要恢复这种异常的话 ;– 转变 SQLException 为一个 unchecked

exception ,如果客户端对这种异常无能为力的话 ( 多数情况 );

Page 16: COMMON JAVA JAVA 数据结构与常用类库简介

使用异常最佳实践• 总是要做一些清理工作 (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.

Page 17: COMMON JAVA JAVA 数据结构与常用类库简介

Add Java Exception Breakpoint

Page 18: COMMON JAVA JAVA 数据结构与常用类库简介

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);   }

Page 19: COMMON JAVA JAVA 数据结构与常用类库简介

@Annotations

Page 20: COMMON JAVA JAVA 数据结构与常用类库简介

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}

Page 21: COMMON JAVA JAVA 数据结构与常用类库简介

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@MarkerAnnotationvoid method4() { … }

Page 22: COMMON JAVA JAVA 数据结构与常用类库简介

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();

}

Page 23: COMMON JAVA JAVA 数据结构与常用类库简介

Annotation Targets in Java 5@A package some.package.name;

@B class MyClass { @C Object field;

@D MyClass(@E Object param) { field = param; }

@F Object method() { @G Object localVar = field; return localVar; }}

Page 24: COMMON JAVA JAVA 数据结构与常用类库简介

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

Page 25: COMMON JAVA JAVA 数据结构与常用类库简介

告知程序如何处理 @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接口

Page 26: COMMON JAVA JAVA 数据结构与常用类库简介

Java Logging

Page 27: COMMON JAVA JAVA 数据结构与常用类库简介

Logging use-cases

• debugging the software during development• help diagnose bugs during production• trace access for security purposes• create data for statistical use• etc

Page 28: COMMON JAVA JAVA 数据结构与常用类库简介

History

• System.out.println()• System.err.println()• e.printStackTrace()

Page 29: COMMON JAVA JAVA 数据结构与常用类库简介

Components

Aplicaction Logger

Level/ Priority

Appender

Filter Layout

1..*

Page 30: COMMON JAVA JAVA 数据结构与常用类库简介

Logger Named HierarchyA logger is said to be an ancestor of another logger if its name followed by a dot is the prefix part in thedescendant logger name. PS: 大小写敏感

rootcom.site.softwarecom.site.software.modelcom.site.software.model.daocom.site.software.model.dao.PersonDAOImplcom.site.software.view

●com.site.software is an ancestor logger of the descendantcom.site.software.model.dao

●com.site.software is the parent logger of the childcom.site.software.model

Page 31: COMMON JAVA JAVA 数据结构与常用类库简介

LevelsA logger may be assigned to a level.

Properties configuration filelog4j.rootLogger=ERRORlog4j.logger.com.site.software=INFO

XML configuration file

Java configuration fileLogger.getRootLogger().setLevel(Level.ERROR);Logger.getLogger(“com.site.software”).setLevel(Level.INFO);

levels are orderedTRACE < DEBUG < INFO < WARN < ERROR < FATAL

Page 32: COMMON JAVA JAVA 数据结构与常用类库简介

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.

Page 33: COMMON JAVA JAVA 数据结构与常用类库简介

Level InheritanceThe inherited level for a given logger L, is equal tothe first non-null level in the logger named hierarchy,starting at L and proceeding upwards in thehierarchy towards the root logger.Logger Name Assigned Inherited

Level levelrootcom.site.softwarecom.site.software.modelcom.site.software.model.daocom.site.software.model.dao.PersonDAOImplcom.site.software.view

ERRORWARNINFOnullnullnull

ERRORWARNINFOINFOINFO

WARN

Page 34: COMMON JAVA JAVA 数据结构与常用类库简介

Level 继承 1Logger name Assigned level Effective levelroot DEBUG DEBUGX none DEBUGX.Y none DEBUGX.Y.Z none DEBUG

Logger name Assigned level Effective levelroot ERROR ERRORX INFO INFOX.Y DEBUG DEBUGX.Y.Z WARN WARN

Page 35: COMMON JAVA JAVA 数据结构与常用类库简介

Level 继承 2Logger name Assigned level Effective levelroot DEBUG DEBUGX INFO INFOX.Y none INFOX.Y.Z ERROR ERROR

Logger name Assigned level Effective levelroot DEBUG DEBUGX INFO INFOX.Y none INFOX.Y.Z none INFO

Page 36: COMMON JAVA JAVA 数据结构与常用类库简介

Logging RequestA log request of level p in a logger configured (eitherassigned or inherited, whichever is appropriate) withlevel 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");

Page 37: COMMON JAVA JAVA 数据结构与常用类库简介

AppendersA logger may be assigned to an appender: a namedoutput destination your log messages are forwardedto.

# The root logger logs to the consolelog4j.rootLogger=ERROR, con

# The com.site.software logger logs to a filelog4j.logger.com.site.software=INFO, FileApp

# The con appender will log in the consolelog4j.appender.con=org.apache.log4j.ConsoleAppender

#The FileApp appender will log in a filelog4j.appender.FileApp=org.apache.log4j.FileAppender

Page 38: COMMON JAVA JAVA 数据结构与常用类库简介

Appenders

Page 39: COMMON JAVA JAVA 数据结构与常用类库简介

Appender AdditivityEach enabled logging request for a given logger Lwill be forwarded to all the appenders in that loggerLA as well as all the appenders higher HA in thelogger named hierarchy .

LAconnull

FileApp, cde

Logger Namerootcom.site.softwarecom.site.software.modelcom.site.software.model.daocom.site.software.view

HA

concon

FileApp, c, concon

Page 40: COMMON JAVA JAVA 数据结构与常用类库简介

Additivity FlagLogger Name

Attached Appenders

Additivity Flag Output Targets Comment

root A1not applicable

A1Since 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 true A1, A-x1, A-x2 Appenders of "x" and of root.

x.y.z A-xyz1 true A1, A-x1, A-x2, A-xyz1 Appenders of "x.y.z", "x" and of root.

security A-sec false A-secNo appender accumulation since the additivity flag is set to false. Only appender A-sec will be used.

security.access none true A-sec

Only appenders of "security" because the additivity flag in "security" is set to false.

Page 41: COMMON JAVA JAVA 数据结构与常用类库简介

Layout Conversion Pattern

log4j.appender.con=org.apache.log4j.ConsoleAppenderlog4j.appender.con.layout=org.apache.log4j.PatternLayoutlog4j.appender.con.layout.ConversionPattern=%d [%t] %-5p %m (%c:%L)%n

Produced logs:2010-05-14 19:29:11,996 [main] INFO You will see me in the log becauseinfo = INFO (com.site.software.model.dao.PersonDAOImpl:10)2010-05-14 19:29:11,997 [main] WARNYou will see me in the log becausewarn > INFO (com.site.software.model.dao.PersonDAOImpl:11)

Each appender has a layout component responsiblefor formatting log messages accordingly toconversion patterns.

Page 42: COMMON JAVA JAVA 数据结构与常用类库简介

A lot of Appenders and LayoutsAppenders

● 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 e-mail 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

Page 43: COMMON JAVA JAVA 数据结构与常用类库简介

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: }

Page 44: COMMON JAVA JAVA 数据结构与常用类库简介

SLF4J & Logback

logback 的前世今生• slf4j 由 log4j 作者 Ceki 开发,逐步取代

apahce commons logging 。• logback 由 log4j 作者 Ceki 开发,逐步取代

log4j 。

Page 45: COMMON JAVA JAVA 数据结构与常用类库简介

logback 相比较 log4j 的优势• slf4j 支持参数化

– logger.error(“ 帐号 ID : {} 不存在” , userId);– 告别了 if(logger.isDebugEnable()) 时代

• 另外 logback 的整体性能比 log4j 也较佳,hibernate 等项目已经采用了 slf4j 。

Page 46: COMMON JAVA JAVA 数据结构与常用类库简介

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

Page 47: COMMON JAVA JAVA 数据结构与常用类库简介

Why Logback

• Conditional Processing– Good For Dev/Prod switch

Is It Worth A Use?

Page 48: COMMON JAVA JAVA 数据结构与常用类库简介

Why LogbackStack Traces Pointing jar files

Page 49: COMMON JAVA JAVA 数据结构与常用类库简介

logback.xml

ConsoleAppender

RollingFileAppender

rollover daily or whenever the file size reaches 100MB

Page 50: COMMON JAVA JAVA 数据结构与常用类库简介
Page 51: COMMON JAVA JAVA 数据结构与常用类库简介
Page 52: COMMON JAVA JAVA 数据结构与常用类库简介

Parameterized logginginefficient syle

logger.debug("Hello "+name);

old style:

if(logger.isDebugEnabled()) { logger.debug("Hello "+name); }

new style:

logger.debug("Hello {}", name);

Page 53: COMMON JAVA JAVA 数据结构与常用类库简介

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

Page 54: COMMON JAVA JAVA 数据结构与常用类库简介

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> </appender>

Page 55: COMMON JAVA JAVA 数据结构与常用类库简介

Mapped Diagnostic Context(MDC)

• 线程映射表• 日志框架维护的 map ,日志框架通过提供了的键值对向其中插入日志信息。映射诊断环境(Mapped Diagnostic Context)Logback 的设计目标之一是审查和调试复杂的分布式应用程序。真实世界的多数分布式系统需要同时处理多个客户端。在一个典型的多线程方式实现的分布式系统里,不同的线程处理不同的客户端。区分不同客户端的记录输出的一个可行的但不好的方法是为每个客户端都创建新的、独立的 logger 。这种技术使 logger 的数量增多且大大增加了管理开销。 一个轻量的技术是为客户端的每个记录请求添加唯一戳( uniquely stamp) Logback 在 SLJ4J里使用了这种技术的一种变体:映射诊断环境(MDC) 为了给每个请求添加唯一戳,用户把环境( context)信息放进MDContext) 

Page 56: COMMON JAVA JAVA 数据结构与常用类库简介

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()); }

Page 57: COMMON JAVA JAVA 数据结构与常用类库简介

MDC Use Case: User Based Loggingpublic 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); } }}

Page 58: COMMON JAVA JAVA 数据结构与常用类库简介

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>

Page 59: COMMON JAVA JAVA 数据结构与常用类库简介

MDC Use Case: InsertingServletFilter

• %X{req.remoteHost}• %X{req.requestURI}%n%d - %m%n

Page 60: COMMON JAVA JAVA 数据结构与常用类库简介

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..

Page 61: COMMON JAVA JAVA 数据结构与常用类库简介

JAVA String

Page 62: COMMON JAVA JAVA 数据结构与常用类库简介

String

Page 63: COMMON JAVA JAVA 数据结构与常用类库简介

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

Page 64: COMMON JAVA JAVA 数据结构与常用类库简介

(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

Guava SplitterJDK has splitter

‣ regular expression‣ result as an array‣ its way of handling empty pieces

Page 65: COMMON JAVA JAVA 数据结构与常用类库简介

SplitterBreaks 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 lengthSplitter.fixedLength(8)

Iterable<String> pieces =Splitter.on(',').split("trivial,example")

returns "trivial" and "example" in order.

Page 66: COMMON JAVA JAVA 数据结构与常用类库简介

The default behavior is simplistic://yields [" foo", " ", "bar", " quux", ""]Splitter.on(',').split(" foo, ,bar, quux,");

//yields ["foo", "bar", "quux"]Splitter.on(',') .trimResults() .omitEmptyStrings() .split(" foo, ,bar, quux,");

If you want extra features,ask for them!

Page 67: COMMON JAVA JAVA 数据结构与常用类库简介

Guava JoinerBizarrely 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(":");

Page 68: COMMON JAVA JAVA 数据结构与常用类库简介

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)

Page 69: COMMON JAVA JAVA 数据结构与常用类库简介

对象的字符串表示方法• 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)

Page 70: COMMON JAVA JAVA 数据结构与常用类库简介

BASE64

01 import static javax.xml.bind.DatatypeConverter.parseBase64Binary;02 import static javax.xml.bind.DatatypeConverter.printBase64Binary;03 04 @Test05 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 }

Page 71: COMMON JAVA JAVA 数据结构与常用类库简介

JAVA IO

Page 72: COMMON JAVA JAVA 数据结构与常用类库简介

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

Page 73: COMMON JAVA JAVA 数据结构与常用类库简介

Stream Concept

Page 74: COMMON JAVA JAVA 数据结构与常用类库简介

Java I/O Classes• Text 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).

Page 75: COMMON JAVA JAVA 数据结构与常用类库简介

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)

Page 76: COMMON JAVA JAVA 数据结构与常用类库简介

Reader <-> InputStreamWriter <->WriterOutputStream

• Reader->InputStream commons-io :ReaderInputStream • Writer->OutputStream commons-io :WriterOutputStream• InputStream->Reader jdk:InputStreamReader• OutputStream->Writer jdk:OutputStreamWriter• InputStream->OutputStream?• Reader->Writer?

Page 77: COMMON JAVA JAVA 数据结构与常用类库简介

Closeable

• Reader 何时关闭 ?• Writer 何时关闭 ?• InputStream 何时关闭 ?• OutputStream 何时关闭 ?

Page 78: COMMON JAVA JAVA 数据结构与常用类库简介

FileUtils

Page 79: COMMON JAVA JAVA 数据结构与常用类库简介

2 key interfacespublic interface InputSupplier<T> { T getInput() throws IOException;}public interface OutputSupplier<T> { T getOutput() throws IOException;}

Guava common.io

Typically:InputSupplier<InputStream>,OutputSupplier<Writer>,etc.

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

Page 80: COMMON JAVA JAVA 数据结构与常用类库简介

common.io: ByteStreamsbyte[] 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 andCharSequence (often requiring you to specify a Charset).

Page 81: COMMON JAVA JAVA 数据结构与常用类库简介

common.io: Files

The Files class works one level higher than ByteStreams andCharStreams, 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)

Page 82: COMMON JAVA JAVA 数据结构与常用类库简介

More about FilesFile 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)

Page 83: COMMON JAVA JAVA 数据结构与常用类库简介

Flushables and CloseablesbFlushables.flushQuietly(Flushable flushable)Flushables.flush(

Flushable flushable,boolean swallowIOException) throws IOException

Closeables.closeQuietly(Closeable closeable)Closeables.close(

Closeable closeable,boolean swallowIOException) throws IOException

Very usefull in finally blocks(avoid nesting try/catch)

Page 84: COMMON JAVA JAVA 数据结构与常用类库简介

Java Collections

Page 85: COMMON JAVA JAVA 数据结构与常用类库简介

Java array and collections

Page 86: COMMON JAVA JAVA 数据结构与常用类库简介

JAVA Collections

Page 87: COMMON JAVA JAVA 数据结构与常用类库简介

Java Collection Interfaces

4种基本形式,前三种的父接口是 Collection。1 : List 关注对象的索引列表2 : Set 关注对象的唯一性3 : Queue 关注对象被处理时的顺序4 : Map 关注映射和键值的唯一性

Page 88: COMMON JAVA JAVA 数据结构与常用类库简介
Page 89: COMMON JAVA JAVA 数据结构与常用类库简介
Page 90: COMMON JAVA JAVA 数据结构与常用类库简介

Collection Utilities

Page 91: COMMON JAVA JAVA 数据结构与常用类库简介

List具体实现类

Page 92: COMMON JAVA JAVA 数据结构与常用类库简介

Map具体实现类

Page 93: COMMON JAVA JAVA 数据结构与常用类库简介

Set具体实现类

Page 94: COMMON JAVA JAVA 数据结构与常用类库简介

Queue具体实现类

Page 95: COMMON JAVA JAVA 数据结构与常用类库简介
Page 96: COMMON JAVA JAVA 数据结构与常用类库简介

Multiset

Page 97: COMMON JAVA JAVA 数据结构与常用类库简介

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>)

Page 98: COMMON JAVA JAVA 数据结构与常用类库简介

Multimap Implementations

Page 99: COMMON JAVA JAVA 数据结构与常用类库简介

BiMap

BiMap<K, V> is Map<K,V> with unique values

Operations: all Map, inverse(), values() as Set

Throws an IllegalArgumentException if youattempt to map a key to an already-presentvalue

Page 100: COMMON JAVA JAVA 数据结构与常用类库简介

BiMap Implementations

Page 101: COMMON JAVA JAVA 数据结构与常用类库简介

Table

Page 102: COMMON JAVA JAVA 数据结构与常用类库简介

Copy!Lists.newArrayList()Lists.newLinkedList()Sets.newHashSet()Sets.newLinkedHashSet()Sets.newTreeSet()

ImmutableList.copyOf()ImmutableSet.copyOf()

or make it immutable...

Page 103: COMMON JAVA JAVA 数据结构与常用类库简介

不同集合类型有不同的时间复杂度Operation ArrayList LinkedList HashSet TreeSet

Obtain size Constant Constant Constant ConstantAdd element Constant Constant Constant LogRemove given element Linear Linear Constant LogRemove by index Linear Linear – –Get element by index Constant Linear – –Find out if contains Linear Linear Constant Log

Depending on the size, different types of collections may behave better that others

Page 104: COMMON JAVA JAVA 数据结构与常用类库简介

how to choose correct java collection class (When to use which collection in java )

Page 105: COMMON JAVA JAVA 数据结构与常用类库简介

泛型练习• 泛型改造MyStack• 增加方法 : pushAll• 增加方法 : popAll

MyStack.java

@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); }

MyStackTest.javaMyStack.java

Page 106: COMMON JAVA JAVA 数据结构与常用类库简介

The Get and Put Principlepublic 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

Page 107: COMMON JAVA JAVA 数据结构与常用类库简介

Misc.

• Tuples• The of-Operator• ULong, UInt, UShort

Page 108: COMMON JAVA JAVA 数据结构与常用类库简介

Java Reflections

Page 109: COMMON JAVA JAVA 数据结构与常用类库简介

Metadatan Java stores metadata in classes

-

-

-

-

Metadata for a class:Metadata for a constructor:Metadata for a field:Metadata for a method:

java.lang.Classjava.lang.reflect.Constructorjava.lang.reflect.Fieldjava.lang.reflect.Method

n

n

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- Examples are shown on the next slide

Page 110: COMMON JAVA JAVA 数据结构与常用类库简介

Examples of inter-relatedness of reflection classes

class Class {Constructor[]FieldField[]Method[]

getConstructors();getDeclaredField(String name);getDeclaredFields();getDeclaredMethods();

...}

class Field {Class getType();...

}

class Method {Class[] getParameterTypes();

getReturnType();Class...

}

Page 111: COMMON JAVA JAVA 数据结构与常用类库简介

Metadata for primitive types and arraysJava associates a Class instance with each primitive type:Class c1 = int.class;Class c2 = boolean.class;Class c3 = void.class;

Use Class.forName() to access the Class object for an arrayClassClassClassClass

c4c5c6c7

====

byte.class; // byteClass.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 à booleanUse as many “[”s as there are dimensions in the array

Might be returned byMethod.getReturnType()

Page 112: COMMON JAVA JAVA 数据结构与常用类库简介

Miscellaneous Class methods

Here are some useful methods defined in Classclass Class {

public String getName(); // fully-qualified namepublic boolean isArray();public boolean isInterface();public boolean isPrimitive();public Class getComponentType(); // only for arrays...

}

Page 113: COMMON JAVA JAVA 数据结构与常用类库简介

Invoking a default constructorUse Class.newInstance() to call the default constructorExample:

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(...);

Page 114: COMMON JAVA JAVA 数据结构与常用类库简介

A plug-in architectureUse a properties file to store a mapping forplugin name à class nameMany tools support plugins: Ant, Maven, Eclipse, …

abstract class Plugin {abstract void op1(...);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(“...”);

Page 115: COMMON JAVA JAVA 数据结构与常用类库简介

Invoking a non-default constructorSlightly 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(“...”);

Page 116: COMMON JAVA JAVA 数据结构与常用类库简介

Passing primitive types as parametersIf you want to pass a primitive type as a parameter:

Wrap the primitive value in an object wrapperThen use the object wrapper as the parameter

Object wrappers for primitive types:àààà

java.lang.Booleanjava.lang.Bytejava.lang.Characterjava.lang.Integer

-

-

-

-

-

booleanbytecharint...

Page 117: COMMON JAVA JAVA 数据结构与常用类库简介

Invoking a methodBroadly 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”});

Page 118: COMMON JAVA JAVA 数据结构与常用类库简介

Looking up methodsThe API for looking up methods is fragmented:

-

-

You can lookup a public method in a class or its ancestor classesOr, lookup a public or non-public method declared in the specified class

class Class {public Method getMethod(String name,

Class[] parameterTypes);public Method[] getMethods();public Method getDeclaredMethod(String name,

Class[] parameterTypes);public Method[] getDeclaredMethods();...

}

A better namewould have been

getPublicMethod()

Page 119: COMMON JAVA JAVA 数据结构与常用类库简介

Finding an inherited methodThis 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;

}

Page 120: COMMON JAVA JAVA 数据结构与常用类库简介

Accessing a fieldThere 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);

Page 121: COMMON JAVA JAVA 数据结构与常用类库简介

Looking up fields

would have beengetPublicField()

The API for looking up fields is fragmented:-

-

You can lookup a public field in a class or its ancestor classesOr, lookup a public or non-public field declared in the specified class

class Class {public Fieldpublic Field[]public Fieldpublic Field[]...

}

A better namewould have been

getPublicField()

getField(String name);getFields();getDeclaredField(String name);getDeclaredFields();

Page 122: COMMON JAVA JAVA 数据结构与常用类库简介

Finding an inherited fieldThis 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;

}

Page 123: COMMON JAVA JAVA 数据结构与常用类库简介

Java modifiersn Java defines 11 modifiers:

- abstract, final, native, private, protected, public, static,strictfp, synchronized, transient and volatile

n Some of the modifiers can be applied to a class, method orfield:

-

-

Set of modifiers is represented as bit-fields in an integerAccess set of modifiers by calling int getModifiers()

n Useful static methods on java.lang.reflect.Modifier:booleanbooleanbooleanboolean

isAbstract(int modifier);isFinal(int modifier);isNative(int modifier);isPrivate(int modifier);

staticstaticstaticstatic...

Page 124: COMMON JAVA JAVA 数据结构与常用类库简介

Accessing non-public fields and methods

Hibernate uses this techniqueso it can serialize non-public

n

n

n

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);

Page 125: COMMON JAVA JAVA 数据结构与常用类库简介

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

Page 126: COMMON JAVA JAVA 数据结构与常用类库简介

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");

Page 127: COMMON JAVA JAVA 数据结构与常用类库简介

Comparison with standard java.lang.reflect

jOOR code:

Employee[] employees = on(department).call("getEmployees").get();

for (Employee employee : employees) {  Street street = on(employee).call("getAddress").call("getStreet").get();  System.out.println(street);}

The same example with normal reflection in Java:

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);}

Page 128: COMMON JAVA JAVA 数据结构与常用类库简介

JavaScript Object Notation

Page 129: COMMON JAVA JAVA 数据结构与常用类库简介

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"}

Page 130: COMMON JAVA JAVA 数据结构与常用类库简介

JSON Form View JSONFormView.htm

Page 131: COMMON JAVA JAVA 数据结构与常用类库简介

What is JSON?

• Lightweight data-interchange 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

Page 132: COMMON JAVA JAVA 数据结构与常用类库简介

Why Use JSON over XML

• Lighter and faster than XML as on-the-wire dataformat

• 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 JavaScriptcode vs. XML data needed to be parsed and assigned tovariables through tedious DOM APIs

> Retrieving values is as easy as reading from an objectproperty in your JavaScript code

Page 133: COMMON JAVA JAVA 数据结构与常用类库简介

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

Page 134: COMMON JAVA JAVA 数据结构与常用类库简介

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);

Page 135: COMMON JAVA JAVA 数据结构与常用类库简介

JSON Schema{"$schema" : "http://json-schema.org/draft-03/schema#","id" : "http://json-schema.org/draft-03/schema#","type" : "object",

"properties" : {"type" : {"type" : ["string", "array"],"items" : {"type" : ["string", {"$ref" : "#"}]},"uniqueItems" : true,"default" : "any"},

"properties" : {"type" : "object","additionalProperties" : {"$ref" : "#"},"default" : {}},

Page 136: COMMON JAVA JAVA 数据结构与常用类库简介

XML tools

XMLTag tag = XMLDoc.newDocument(false)    .addDefaultNamespace("http://www.w3.org/2002/06/xhtml2/")    .addNamespace("wicket", "http://wicket.sourceforge.net/wicket-1.0")    .addRoot("html")    .addTag("wicket:border")    .gotoRoot().addTag("head")    .addNamespace("other", "http://other-ns.com")    .gotoRoot().addTag("other:foo");System.out.println(tag.toString());

http://code.google.com/p/xmltool/

Page 137: COMMON JAVA JAVA 数据结构与常用类库简介

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 !

Page 138: COMMON JAVA JAVA 数据结构与常用类库简介

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", "2011-08-14"),             $("amount", "155"),             $("paid", "false"),             $("settled", "false")).attr("id", "13");

Page 139: COMMON JAVA JAVA 数据结构与常用类库简介

JOOQSELECT * FROM BOOKWHERE 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 > '2008-01-01' 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("2008-01-01")))       .groupBy(FIRST_NAME, LAST_NAME)       .having(count().greaterThan(5))       .orderBy(LAST_NAME.asc()      .nullsFirst())      .limit(2).offset(1)      .forUpdate()       .of(FIRST_NAME, LAST_NAME)

Page 140: COMMON JAVA JAVA 数据结构与常用类库简介

JOOQ + H201 import org.jooq.util.h2.H2Factory;02 import cn.bingoo.h2.domain.Tables;03 import cn.bingoo.h2.domain.tables.records.VouchercardRecord;04 05 @Test06 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 }

Page 141: COMMON JAVA JAVA 数据结构与常用类库简介

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 digitabc|xyz match either abc or xyz[A-Za-z]+[0-9] match one or more letters immediately followed by one digit

Page 142: COMMON JAVA JAVA 数据结构与常用类库简介

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

Quantifiers(限定符 )X* 0 or moreX+ 1 or moreX? 0 or 1X{3} Exactly 3X{3,} 3 or moreX{3,5} 3, 4 or 5Add a ? to a quantifier to make it ungreedy.

Groups and Ranges(分组和范围 ). Any character except new line (\n)(a|b) a or b(...) Group(?:...) Passive (non-c apt uring) 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/ sub patternRanges are inclusive.

Character Classes(字符分类 )\c Control character 控制字符\s White space 空白字符\S Not white space 非空白\d Digit 数字\D Not digit 非数字\w Word 单词\W Not word 非单词\x Hexade cimal digit 16进制\O Octal digit 8进制

REGEX

Page 143: COMMON JAVA JAVA 数据结构与常用类库简介

限定符类型 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}+

Page 144: COMMON JAVA JAVA 数据结构与常用类库简介

限定符示例• 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

Page 145: COMMON JAVA JAVA 数据结构与常用类库简介

JAVA 中的 Regex01 import java.util.regex.Matcher;02 import java.util.regex.Pattern;03 04 @Test05 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 }

Page 146: COMMON JAVA JAVA 数据结构与常用类库简介

分组 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 ) ) )

1 2 3 4\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

Page 147: COMMON JAVA JAVA 数据结构与常用类库简介

JAVA 中的 regex group 和 replace01 @Test02 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 18 @Test19 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 }

Page 148: COMMON JAVA JAVA 数据结构与常用类库简介

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

Page 149: COMMON JAVA JAVA 数据结构与常用类库简介

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)

Page 150: COMMON JAVA JAVA 数据结构与常用类库简介

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 Modifiersg Global matchi Case-i nse nsitivem Multiple liness Treat string as single linex Allow comments and white space in patterne Evaluate replac ementU Ungreedy pattern

Assertions?= Lookahead assertion?! Negative lookahead?<= Lookbehind assertion?!= or ?<! Negative lookbehind?> Once-only Subexp ression?() Condition [if then]?()| Condition [if then else]

?# Comment

String Replacement(有的实现使用 \替代$)$n nth non-pa ssive group

$2 " xyz " in /^(abc (xy z))$/

$1 " xyz " in /^(?:a bc) (xyz)$/$` Before matched string$' After matched string

$+ Last matched string$& Entire matched string

Page 151: COMMON JAVA JAVA 数据结构与常用类库简介

RegexBuddy练习1) 匹配字母,数字和减号Letters, digits and hyphens

2) 匹配日期 yyyy-mm-dd

3) jpg, gif 或 png 图片文件名4) Email 地址5) Html tags

6) 至少包括一个大写字母、小写字母和数字(密码强度 )

Page 152: COMMON JAVA JAVA 数据结构与常用类库简介

Scalable language

Page 153: COMMON JAVA JAVA 数据结构与常用类库简介

Pragmatic

Since

2003

runs on the JVM

Seamless Javainteroperability

Statically typedProduction

ready

Martin Odersky

Hybrid

Page 154: COMMON JAVA JAVA 数据结构与常用类库简介

“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

Page 155: COMMON JAVA JAVA 数据结构与常用类库简介

“If I were to pick a language to use today other than Java, it would be Scala.”

James Gosling

Page 156: COMMON JAVA JAVA 数据结构与常用类库简介

Who uses Scala already

Page 157: COMMON JAVA JAVA 数据结构与常用类库简介

一切值都是对象的实例•

JVM 中的原生类型是对象的实例123.toByte"1".toInttrue.toString

函数也是值,从而也是对象的实例val compare = (x: Int, y: Int) => x > ycompare(1, 2) // result: Boolean = false

Java 的 static 方法和域再没有存在的理由,因为它们的所有者也必须是对象的实例 (值 ) ,所以有了 Scala 中的单例 objectobject Dog {

val whatever = "dog" // static field in Java}class Dog {

def callWhatever = Dog.whatever}

Page 158: COMMON JAVA JAVA 数据结构与常用类库简介

函数作为值••

可以当作参数传递val compare = (x: Int, y: Int) => x > ylist 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 的方法调用现在都是值 ( 实例 ) 的方法

Page 159: COMMON JAVA JAVA 数据结构与常用类库简介

一切操作都是函数调用 (1)只有一个参数或零个参数的方法在调用时可以省略” .” 和” ()”1.+(1)1 + 11.>(0)1 > 0(1 > 0).&(2 > 1)(1 > 0) & 2 > 1stack.push(10)stack push 10stack.popstack pop参数也可以是一系列操作 {...}stack push {

valvala +

a = 1b = 2b

}更多的符号需要用作方法名def !@#%^&*\-<=>?|~:/ = println("noop")def √(x: Double) = Math.sqrt(x)val Π = Math.Pival r = √(9*Π)

‘<’, ‘>’更适合作方法名,所以用’ [’ 和‘ ]’ 来表示类型参数

Page 160: COMMON JAVA JAVA 数据结构与常用类库简介

一切操作都是函数调用 (2)•

for语句是函数调用for (i <- List(1, 2)) {

println(i)}List(1, 2) foreach {i => println(i)}

for (i <- List(1, 2)) yield {i + 10

}List(1, 2) map {i => i + 10}

更多的例子// synchronized is function call instead of keyworddef check = synchronized {

// isInstanceOf is function call instead of keyword100.isInstanceOf[String]

}

额外的好处:自左向右顺序书写语句stack.pop.asInstanceOf[Int] // (Integer) stack.pop() in Java

Page 161: COMMON JAVA JAVA 数据结构与常用类库简介

一切操作都返回值• 默认返回最后一条语句的值,也可以用 return显式返回

val r1 = { // return 3val a = 1val b = 2a + b

}

val r2 = if (true) 1 else 2

val r3 = // return (): Unitfor (i <- List(1, 2)) {

println(i)}

val r4 = // return List(11, 12)for (i <- List(1, 2)) yield {

i + 10}

val r5 = // return java.io.Filetry {

val f = new File("afile")f

} catch {case ex: IOException => null

}

Page 162: COMMON JAVA JAVA 数据结构与常用类库简介

Higher Level// 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;

}}

// Scalaval hasUpperCase = name.exists(_.isUpperCase)

Page 163: COMMON JAVA JAVA 数据结构与常用类库简介

// Scalaclass Person( var name: String, var age: Int)

Declaring classes…concisely

// Javapublic 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) { this.name = name; } public void setAge(int age) { this.age = age; }}

Page 164: COMMON JAVA JAVA 数据结构与常用类库简介

Java – working with Person

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";if(x instanceof Person) {

Person p = (Person)x;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, ???");

Scala – Pattern Matching

var x: Any = Person("Lukasz", 28);x match {

case Person(name, age) => println("Person name: "+name);case _ => println("Not a person")

}x = "Lukasz Kuczera"x match {

case Person(name, age) => println("Person name: "+name)

case "Bill Clinton" => println("hello Bill")

case s: String => println("hello "+s)case _ => "err, ???"

}

Person name: Lukaszhello Lukasz Kuczera

Page 165: COMMON JAVA JAVA 数据结构与常用类库简介

Pattern matching…is concise

// Scalareactions += { case m: MouseEntered => println(“I see it!”) case m: MouseExited => println(“Lost it.”) case m: MouseClicked => println(“Poked!”)}

// Javabutton.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

Page 166: COMMON JAVA JAVA 数据结构与常用类库简介

Working with arrays// Javapublic 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();

}}

// Scalaval all: Array[Person]

val (minors, adults) = all.partition(_.age<18)

Page 167: COMMON JAVA JAVA 数据结构与常用类库简介

Duck Typing

class Duck { def quack = "呱 ...呱 ..."}def doQuack(d: {def quack: String}) { println(d.quack)}doQuack(new Duck)

Page 168: COMMON JAVA JAVA 数据结构与常用类库简介

Nice to knowScala:Console.println(“Hello”)println(“Hello”)

val line = Console.readLine()val line = readLine()

error(“Bad”)

1 + 11 .+(1)

1 == new Object1 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”);

Page 169: COMMON JAVA JAVA 数据结构与常用类库简介

“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

学识浅薄是件危险的事情;要么酣饮,不然就尝不到知识源泉的甘霖。在那里浅斟薄饮使头脑醉昏,大量畅饮会使我们清醒。 --亚历山大 ·蒲柏