Lambda表达式常用代码示例

2017-10-24

目录

1 Lambda表达式是什么
2 Lambda表达式语法
3 函数式接口是什么
  3.1 常用函数式接口
4 Lambdas和Streams结合使用
  4.1 使用forEach方法
  4.2 使用过滤器filter方法
  4.3 使用limit方法
  4.4 使用sorted方法
  4.5 使用map方法
  4.6 使用parallelStream方法
  4.7 使用summaryStatistics方法
参考

1 Lambda表达式是什么


返回

Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确。在Java中,Lambda 表达式是对象,他们必须依附于一类特别的对象类型——函数式接口(functional interface))。Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式就和方法一样,它提供了一个正常的参数列表(argument)和一个使用这些参数的主体(body)。

Lambda 表达式为 Java 添加了缺失的函数式编程特点,使我们能将函数当做一等公民看待。

Lambda表达式还增强了集合库。 Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。 总的来说,lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。

2 Lambda表达式语法


返回

Java 中的 Lambda 表达式通常使用 (argument) -> {body} 语法书写,例如:

  1. (arg1, arg2...) -> { body }
  2. (type1 arg1, type2 arg2...) -> { body }

以下是一些 Lambda 表达式的例子:

  1. (int a, int b) -> { return a + b; }
  2. () -> System.out.println("Hello World");
  3. (String s) -> { System.out.println(s); }
  4. () -> 42
  5. () -> { return 3.1415 };

Lambda表达式结构说明:

  • 一个 Lambda 表达式可以有零个或多个参数
  • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
  • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
  • 空圆括号代表参数集为空。例如:() -> 42
  • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
  • Lambda 表达式的主体可包含零条或多条语句
  • 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
  • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

3 函数式接口是什么


返回

函数式接口是只包含一个抽象方法声明的接口。

java.lang.Runnable 就是一种函数式接口,在 Runnable 接口中只声明了一个方法 void run(),相似地,ActionListener 接口也是一种函数式接口,我们使用匿名内部类来实例化函数式接口的对象,有了 Lambda 表达式,这一方式可以得到简化。Runnable接口代码如下:

  1. @FunctionalInterface
  2. public interface Runnable {
  3. public abstract void run();
  4. }

每个 Lambda 表达式都能隐式地赋值给函数式接口。如下代码:

  1. Runnable r = () -> System.out.println("hello world");

Runnable的Lambda表达式和匿名内部类的使用示例

  1. public void sample01() {
  2. // 1.1使用匿名内部类
  3. new Thread(new Runnable() {
  4. @Override
  5. public void run() {
  6. System.out.println("1.1 Hello world !");
  7. }
  8. }).start();
  9.  
  10. // 1.2使用 lambda expression
  11. new Thread(() -> System.out.println("1.2 Hello world !")).start();
  12.  
  13. // 2.1使用匿名内部类
  14. Runnable race1 = new Runnable() {
  15. @Override
  16. public void run() {
  17. System.out.println("1.3 Hello world !");
  18. }
  19. };
  20.  
  21. // 2.2使用 lambda expression
  22. Runnable race2 = () -> System.out.println("1.4 Hello world !");
  23.  
  24. // 直接调用 run 方法(没开新线程哦!)
  25. race1.run();
  26. race2.run();
  27. }

自定义函数式接口及Lambda表达式和匿名内部类的使用示例

WorkerInterface.java

  1. //定义一个函数式接口
  2. @FunctionalInterface
  3. public interface WorkerInterface {
  4. public void doSomeWork();
  5. }

WorkerInterfaceTest.java

  1. public class WorkerInterfaceTest {
  2. public static void main(String [] args) {
  3. //invoke doSomeWork using Annonymous class
  4. execute(new WorkerInterface() {
  5. @Override
  6. public void doSomeWork() {
  7. System.out.println("Worker invoked using Anonymous class");
  8. }
  9. });
  10.  
  11. //invoke doSomeWork using Lambda expression
  12. execute( () -> System.out.println("Worker invoked using Lambda expression") );
  13. }
  14.  
  15. public static void execute(WorkerInterface worker) {
  16. worker.doSomeWork();
  17. }
  18. }

3.1 常用函数式接口

Predicate、Function、Consumer、Supplier示例代码:

  1. //Predicate 接口只有一个参数,返回boolean类型。。
  2. Predicate<String> predicate = (s) -> s.length() > 3;
  3. System.out.println(predicate.test("foo")); // false
  4. Predicate<Boolean> nonNull = Objects::nonNull;
  5. System.out.println(nonNull.test(false)); // true
  6.  
  7. //Function 接口接受一个参数,返回一个结果,并附带了一些可以和其他函数组合的默认方法(compose, andThen)
  8. Function<String, Integer> toInteger = Integer::valueOf;
  9. System.out.println(toInteger.apply("123").getClass()); //class java.lang.Integer
  10. Function<String, String> backToString = toInteger.andThen(String::valueOf);
  11. System.out.println(backToString.apply("123").getClass()); //class java.lang.String
  12.  
  13. //Consumer 接口接受一个参数,没有返回结果。
  14. Consumer<Cat> greeter = (c) -> System.out.println("Hello, " + c.name);
  15. Cat cat=new Cat("Tom", 3);
  16. greeter.accept(cat); //Hello, Tom
  17.  
  18. //Supplier接口没有参数,。
  19. Supplier<Double> number = () -> Math.random();
  20. System.out.println(number.get()); //0.8765252430762529

使用Lambdas排序集合

在Java中,Comparator 类被用来排序集合。

使用匿名内部类或Lambda表达式根据 name 排序 players:

  1. String[] players = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka", "David Ferrer",
  2. "Roger Federer", "Andy Murray", "Tomas Berdych", "Juan Martin Del Potro",
  3. "Richard Gasquet", "John Isner"};
  4.  
  5. // 1.1 使用匿名内部类根据 name 排序 players
  6. Arrays.sort(players, new Comparator<String>() {
  7. @Override
  8. public int compare(String s1, String s2) {
  9. return (s1.compareTo(s2));
  10. }
  11. });
  12.  
  13. // 1.2 使用 lambda expression 排序 players
  14. Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
  15. Arrays.sort(players, sortByName);
  16.  
  17. // 1.3 也可以采用如下形式:
  18. Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));

其他排序:

  1. // 2.1 使用匿名内部类根据 surname 排序 players
  2. Arrays.sort(players, new Comparator<String>() {
  3. @Override
  4. public int compare(String s1, String s2) {
  5. return (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))));
  6. }
  7. });
  8.  
  9. // 2.2 使用 lambda expression 排序,根据 surname
  10. Comparator<String> sortBySurname = (String s1, String s2) ->
  11. ( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) );
  12. Arrays.sort(players, sortBySurname);
  13.  
  14. // 2.3 或者这样,怀疑原作者是不是想错了,括号好多...
  15. Arrays.sort(players, (String s1, String s2) ->
  16. ( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) )
  17. );
  18.  
  19. // 3.1 使用匿名内部类根据 name lenght 排序 players
  20. Arrays.sort(players, new Comparator<String>() {
  21. @Override
  22. public int compare(String s1, String s2) {
  23. return (s1.length() - s2.length());
  24. }
  25. });
  26.  
  27. // 3.2 使用 lambda expression 排序,根据 name lenght
  28. Comparator<String> sortByNameLenght = (String s1, String s2) -> (s1.length() - s2.length());
  29. Arrays.sort(players, sortByNameLenght);
  30.  
  31. // 3.3 or this
  32. Arrays.sort(players, (String s1, String s2) -> (s1.length() - s2.length()));
  33.  
  34. // 4.1 使用匿名内部类排序 players, 根据最后一个字母
  35. Arrays.sort(players, new Comparator<String>() {
  36. @Override
  37. public int compare(String s1, String s2) {
  38. return (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
  39. }
  40. });
  41.  
  42. // 4.2 使用 lambda expression 排序,根据最后一个字母
  43. Comparator<String> sortByLastLetter =
  44. (String s1, String s2) ->
  45. (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
  46. Arrays.sort(players, sortByLastLetter);
  47.  
  48. // 4.3 or this
  49. Arrays.sort(players, (String s1, String s2) -> (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1)));

4 Lambdas和Streams结合使用


返回

Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。 同样,Stream使用懒运算,他们并不会真正地读取所有数据,遇到像getFirst() 这样的方法就会结束链式语法。

Person.java代码:

  1. public class Person {
  2. private String firstName;
  3. private String lastName;
  4. private String job;
  5. private String gender;
  6. private int salary;
  7. private int age;
  8.  
  9. public Person(String firstName, String lastName, String job,
  10. String gender, int age, int salary) {
  11. this.setFirstName(firstName);
  12. this.setLastName(lastName);
  13. this.setGender(gender);
  14. this.setAge(age);
  15. this.setJob(job);
  16. this.setSalary(salary);
  17. }
  18.  
  19. public String getFirstName() {
  20. return firstName;
  21. }
  22.  
  23. public void setFirstName(String firstName) {
  24. this.firstName = firstName;
  25. }
  26.  
  27. public String getLastName() {
  28. return lastName;
  29. }
  30.  
  31. public void setLastName(String lastName) {
  32. this.lastName = lastName;
  33. }
  34.  
  35. public String getJob() {
  36. return job;
  37. }
  38.  
  39. public void setJob(String job) {
  40. this.job = job;
  41. }
  42.  
  43. public String getGender() {
  44. return gender;
  45. }
  46.  
  47. public void setGender(String gender) {
  48. this.gender = gender;
  49. }
  50.  
  51. public int getSalary() {
  52. return salary;
  53. }
  54.  
  55. public void setSalary(int salary) {
  56. this.salary = salary;
  57. }
  58.  
  59. public int getAge() {
  60. return age;
  61. }
  62.  
  63. public void setAge(int age) {
  64. this.age = age;
  65. }
  66. }

初始化Person代码:

  1. List<Person> javaProgrammers = new ArrayList<Person>() {
  2. {
  3. add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000));
  4. add(new Person("Tamsen", "Brittany", "Java programmer", "female", 23, 1500));
  5. add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));
  6. add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));
  7. add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));
  8. add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));
  9. add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));
  10. add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));
  11. add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));
  12. add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));
  13. }
  14. };
  15.  
  16. List<Person> phpProgrammers = new ArrayList<Person>() {
  17. {
  18. add(new Person("Jarrod", "Pace", "PHP programmer", "male", 34, 1550));
  19. add(new Person("Clarette", "Cicely", "PHP programmer", "female", 23, 1200));
  20. add(new Person("Victor", "Channing", "PHP programmer", "male", 32, 1600));
  21. add(new Person("Tori", "Sheryl", "PHP programmer", "female", 21, 1000));
  22. add(new Person("Osborne", "Shad", "PHP programmer", "male", 32, 1100));
  23. add(new Person("Rosalind", "Layla", "PHP programmer", "female", 25, 1300));
  24. add(new Person("Fraser", "Hewie", "PHP programmer", "male", 36, 1100));
  25. add(new Person("Quinn", "Tamara", "PHP programmer", "female", 21, 1000));
  26. add(new Person("Alvin", "Lance", "PHP programmer", "male", 38, 1600));
  27. add(new Person("Evonne", "Shari", "PHP programmer", "female", 40, 1800));
  28. }
  29. };

4.1 使用forEach方法

使用forEach方法显示所有程序员姓名:

  1. System.out.println("所有程序员的姓名:");
  2. javaProgrammers.forEach((p) -> System.out.println(String.format("%s %s; ", p.getFirstName(), p.getLastName())));
  3. phpProgrammers.forEach((p) -> System.out.println(String.format("%s %s; ", p.getFirstName(), p.getLastName())));

ForEach代码:

  1. public interface Iterable<T> {
  2. default void forEach(Consumer<? super T> action) {
  3. Objects.requireNonNull(action);
  4. for (T t : this) {
  5. action.accept(t);
  6. }
  7. }
  8. ...
  9. }

使用forEach方法,增加程序员的工资5%:

  1. System.out.println("给程序员加薪 5% :");
  2. Consumer<Person> giveRaise = e -> e.setSalary(e.getSalary() / 100 * 5 + e.getSalary());
  3. javaProgrammers.forEach(giveRaise);
  4. phpProgrammers.forEach(giveRaise);

4.2 使用过滤器filter方法

  1. System.out.println("下面是月薪超过 $1,400 的PHP程序员:");
  2. phpProgrammers.stream()
  3. .filter((p) -> (p.getSalary() > 1400))
  4. .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
  5.  
  6. // 定义 filters
  7. Predicate<Person> ageFilter = (p) -> (p.getAge() > 25);
  8. Predicate<Person> salaryFilter = (p) -> (p.getSalary() > 1400);
  9. Predicate<Person> genderFilter = (p) -> ("female".equals(p.getGender()));
  10.  
  11. System.out.println("下面是年龄大于 25岁且月薪在$1,400以上的女PHP程序员:");
  12. phpProgrammers.stream()
  13. .filter(ageFilter)
  14. .filter(salaryFilter)
  15. .filter(genderFilter)
  16. .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));

4.3 使用limit方法

使用limit方法可以限制结果集的个数:

  1. System.out.println("最前面的3个 Java programmers:");
  2. javaProgrammers.stream()
  3. .limit(3)
  4. .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
  5.  
  6. System.out.println("最前面的3个女性 Java programmers:");
  7. javaProgrammers.stream()
  8. .filter(genderFilter)
  9. .limit(3)
  10. .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));

4.4 使用sorted方法

使用sorted方法进行排序:

  1. System.out.println("根据 name 排序,并显示前5个 Java programmers:");
  2. List<Person> sortedJavaProgrammers = javaProgrammers
  3. .stream()
  4. .sorted((p, p2) -> (p.getFirstName().compareTo(p2.getFirstName())))
  5. .limit(5)
  6. .collect(toList());
  7.  
  8. sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
  9.  
  10. System.out.println("根据 salary 排序 Java programmers:");
  11. sortedJavaProgrammers = javaProgrammers
  12. .stream()
  13. .sorted( (p, p2) -> (p.getSalary() - p2.getSalary()) )
  14. .collect( toList() );
  15. sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));

使用min和max方法:

  1. System.out.println("工资最低的 Java programmer:");
  2. Person pers = javaProgrammers
  3. .stream()
  4. .min((p1, p2) -> (p1.getSalary() - p2.getSalary()))
  5. .get();
  6.  
  7. System.out.printf("Name: %s %s; Salary: $%,d.", pers.getFirstName(), pers.getLastName(), pers.getSalary());
  8.  
  9. System.out.println("工资最高的 Java programmer:");
  10. Person person = javaProgrammers
  11. .stream()
  12. .max((p, p2) -> (p.getSalary() - p2.getSalary()))
  13. .get();
  14.  
  15. System.out.printf("Name: %s %s; Salary: $%,d.", person.getFirstName(), person.getLastName(), person.getSalary());

4.5 使用map方法

结合 map 方法,我们可以使用 collect 方法来将我们的结果集放到一个字符串,一个 Set 或一个TreeSet中:

  1. System.out.println("将 PHP programmers 的 first name 拼接成字符串:");
  2. String phpDevelopers = phpProgrammers
  3. .stream()
  4. .map(Person::getFirstName)
  5. .collect(joining(" ; ")); // 在进一步的操作中可以作为标记(token)
  6. System.out.println(phpDevelopers); //Jarrod ; Clarette ; Victor ; Tori ; Osborne ; Rosalind ; Fraser ; Quinn ; Alvin ; Evonne
  7.  
  8. System.out.println("将 Java programmers 的 first name 存放到 Set:");
  9. Set<String> javaDevFirstName = javaProgrammers
  10. .stream()
  11. .map(Person::getFirstName)
  12. .collect(toSet());
  13. System.out.println(javaDevFirstName); //[Elsdon, Shawn, Palmer, Addison, Maude, Floyd, Vere, Tamsen, Jayden, Sindy]
  14.  
  15. System.out.println("将 Java programmers 的 last name 存放到 TreeSet:");
  16. TreeSet<String> javaDevLastName = javaProgrammers
  17. .stream()
  18. .map(Person::getLastName)
  19. .collect(toCollection(TreeSet::new));
  20. System.out.println(javaDevLastName); //[Brittany, Corrina, Dene, Donny, Hervey, Jaimie, Jaycob, Jonie, Pam, Randall]

4.6 使用parallelStream方法

当需要为多核系统优化时,可以 parallelStream().forEach(),只是此时原有元素的次序没法保证,并行的情况下将改变串行时操作的行为:

  1. System.out.println("计算付给 Java programmers 的所有money:");
  2. int totalSalary = javaProgrammers
  3. .parallelStream()
  4. .mapToInt(p -> p.getSalary())
  5. .sum();

4.7 使用summaryStatistics方法

使用summaryStatistics方法获得stream 中元素的各种汇总数据:

  1. //计算 count, min, max, sum, and average for numbers
  2. List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
  3. IntSummaryStatistics stats = numbers
  4. .stream()
  5. .mapToInt((x) -> x)
  6. .summaryStatistics();
  7.  
  8. System.out.println("List中最大的数字 : " + stats.getMax());
  9. System.out.println("List中最小的数字 : " + stats.getMin());
  10. System.out.println("所有数字的总和 : " + stats.getSum());
  11. System.out.println("所有数字的平均值 : " + stats.getAverage());

参考

[1] 深入浅出 Java 8 Lambda 表达式

[2] Java中Lambda表达式的使用

[3] Java 8 中的 Streams API 详解

[4] Lambda 表达式讲解

Lambda表达式常用代码示例的更多相关文章

  1. C#委托,匿名方法,Lambda,泛型委托,表达式树代码示例

    第一分钟:委托 有些教材,博客说到委托都会提到事件,虽然事件是委托的一个实例,但是为了理解起来更简单,今天只谈委托不谈事件.先上一段代码: 下边的代码,完成了一个委托应用的演示.一个委托分三个步骤: ...

  2. Java lambda 表达式常用示例

    实体类 package com.lkb.java_lambda.dto; import lombok.Data; /** * @program: java_lambda * @description: ...

  3. Java 8特性探究(1):通往lambda之路与 lambda表达式10个示例

    本文由 ImportNew 函数式接口 函数式接口(functional interface 也叫功能性接口,其实是同一个东西).简单来说,函数式接口是只包含一个方法的接口.比如Java标准库中的ja ...

  4. Java 8 Lambda表达式10个示例【存】

    PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...

  5. java8 快速入门 lambda表达式 Java8 lambda表达式10个示例

    本文由 ImportNew - lemeilleur 翻译自 javarevisited.欢迎加入翻译小组.转载请见文末要求. Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发 ...

  6. Java8 lambda表达式10个示例

    Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...

  7. Java8 lambda表达式10个示例<转>

    例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runna ...

  8. Lambda表达式 简介 语法 示例

    Lambda 表达式也称为闭包,是匿名类的简短形式.Lambda 表达式简化了[单一抽象方法声明接口]的使用,因此 lambda 表达式也称为功能接口. 在 Java SE 7 中,单一方法接口可使用 ...

  9. lambda表达式10个示例——学习笔记

    摘录:http://www.importnew.com/16436.html 1.lambda实现Runnable // Java 8之前: new Thread(new Runnable() { @ ...

随机推荐

  1. JavaScript Window Navigator 浏览器本身的信息

    window.navigator 对象包含有关访问者浏览器的信息. Window Navigator window.navigator 对象在编写时可不使用 window 这个前缀. Navigato ...

  2. FireFox 浏览器插件/扩展开发学习

    2014-11-08 内容存档在evernote,笔记名"FireFox 浏览器插件/扩展开发学习"

  3. 树莓派进阶之路 (003) - Raspberry Pi(树莓派)国内软件源

    树莓派自带的软件源是 deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi 由于网站在国外 ...

  4. CentOS 7.0关闭默认firewall防火墙启用iptables防火墙

    操作系统环境:CentOS Linux release 7.0.1406(Core) 64位CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙步骤. 1.关闭f ...

  5. 安装cacti

    操作介绍如下: http://foreveryan.blog.51cto.com/3508502/775558 安装如下: 英文地址:http://www.cyberciti.biz/faq/fedo ...

  6. Javascript将html转成pdf,下载(html2canvas 和 jsPDF)

    最近碰到个需求,需要把当前页面生成pdf,并下载.弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :) 项目源码地址:https://github.com/linwalker/render-h ...

  7. C# Httpclient客户端操作

    原文地址:https://www.cnblogs.com/Xujg/p/4113387.html HttpClient 当前主流用法,异步请求,自.NET4.5开始可从Nuget包管理中获取. usi ...

  8. Oracle 12C -- 删除PDB

    删除PDB SQL> select con_id,pdb_name,status from cdb_pdbs; CON_ID PDB_NAME STATUS ---------- ------- ...

  9. VC下加载JPG/GIF/PNG图片的两种方法

    转载自:http://blog.sina.com.cn/s/blog_6582aa410100huil.html 仅管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg ...

  10. SharePoint 2013 创建Web Application

    今天继续SharePoint 2013 的探索之旅,之前几篇文章分析了SharePoint 2013的物理拓扑结构,安装,以及逻辑体系结构.在这篇文章中,我将继续Step By Step形式演示如何在 ...