Stream流与Lambda表达式(二) Stream收集器 Collector接口

一、Stream收集器 Collector接口

package com.java.design.java8.Stream;

import com.java.design.java8.entity.Student;
import com.java.design.java8.entity.Students;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @author 陈杨
 */

@SpringBootTest
@RunWith(SpringRunner.class)
public class CollectorDetail {

    private List<Student> students;

    @Before
    public void init() {
        students=new Students().init();
    }

    @Test
    public void testCollectorDetail() {


        //     Collect 收集器 ---- Collector接口

        //     T-->汇聚操作的元素类型 即流中元素类型
        //     A-->汇聚操作的可变累积类型
        //     R-->汇聚操作的结果类型
        //     public interface Collector<T, A, R>

        //     Collector接口   一种可变汇聚操作
        //                    将输入元素累积到可变结果容器中
        //                    在处理完所有输入元素后 可以选择将累积的结果转换为最终表示(可选操作)
        //                    归约操作支持串行与并行
        //     A  mutable reduction operation that  accumulates input elements into a mutable result container,
        //     optionally transforming  the accumulated result into a final representation after all input         elements
        //     have been processed.  Reduction operations can be performed either sequentially  or in parallel.


        //     Collectors 提供 Collector 汇聚实现  实际上是一个Collector工厂
        //     The class {@link Collectors}  provides implementations of many common mutable reductions.

二、Collector 接口组成

    //     Collector 由以下4个函数协同累积到容器 可选的执行最终转换
    //               supplier           创建一个新的结果容器
    //               accumulator累加器   将新数据元素合并到结果容器中
    //               combiner           合并结果容器  处理线程并发
    //               finisher           对容器执行可选的最终转换
    //
    //     A {@code Collector} is specified by four functions that work together to
    //     accumulate entries into a mutable result container, and optionally perform
    //     a final transform on the result.  They are:
    //           creation of a new result container ({@link #supplier()})
    //           incorporating a new data element into a result container ({@link #accumulator()})
    //           combining two result containers into one ({@link #combiner()})
    //           performing an optional final transform on the container ({@link #finisher()})

三、combiner

        /*
         *     A function that accepts two partial results and merges them.  The
         *     combiner function may fold state from one argument into the other and
         *     return that, or may return a new result container.
         *
         *
         *     BinaryOperator<A> combiner();
         */

       /*     supplier创建单个结果容器-->accumulator调用累积功能-->partition结果--分区容器-->combiner合并分区容器

              A sequential implementation of a reduction using a collector would
              create a single result container using the supplier function, and invoke the
              accumulator function once for each input element.  A parallel implementation
              would partition the input, create a result container for each partition,
              accumulate the contents of each partition into a subresult for that partition,
              and then use the combiner function to merge the subresults into a combined
              result.
        */

四、identity associativity 约束

/*
       确保串行与并行结果的一致性,满足约束: identity  associativity
       To ensure that sequential and parallel executions produce equivalent
       results, the collector functions must satisfy an identity and an associativity constraints.
 */

/*     identity 约束:
       对于任何部分累积的结果, 将其与空结果容器组合必须生成等效的结果
       a == combiner.apply(a, supplier.get())

       The identity constraint says that for any partially accumulated result,
       combining it with an empty result container must produce an equivalent
       result.  That is, for a partially accumulated result {@code a} that is the
       result of any series of accumulator and combiner invocations, {@code a} must
       be equivalent to {@code combiner.apply(a, supplier.get())}.
 */

/*     associativity 约束:
       串行计算与并行拆分计算必须产生同等的结果

       The associativity constraint says that splitting the computation must
       produce an equivalent result.  That is, for any input elements {@code t1}
       and {@code t2}, the results {@code r1} and {@code r2} in the computation
       below must be equivalent:

         A a1 = supplier.get();
         accumulator.accept(a1, t1);
         accumulator.accept(a1, t2);
         R r1 = finisher.apply(a1);  // result without splitting

         A a2 = supplier.get();
         accumulator.accept(a2, t1);
         A a3 = supplier.get();
         accumulator.accept(a3, t2);
         R r2 = finisher.apply(combiner.apply(a2, a3));  // result with splitting

 */

五、reduction 汇聚 的实现方式

        //      reduction 汇聚 的实现方式
        //      list.stream().reduce()                        对象不可变
        //      list.stream().collect(Collectors.reducing())  对象可变
        //      单线程可以实现结果一致 但在多线程中就会出现错误

        /*

                 Libraries that implement reduction based on {@code Collector}, such as
                 {@link Stream#collect(Collector)}, must adhere to the following constraints:


                 传递给accumulator的第一个参数,传递给combiner的二个参数,传递给finisher的参数
                 必须是函数(supplier accumulator combiner)上一次调用结果
                 理解: 参数类型A
                 Supplier<A> supplier();
                 BiConsumer<A, T> accumulator();
                 BinaryOperator<A> combiner();
                 Function<A, R> finisher();

                 The first argument passed to the accumulator function, both
                 arguments passed to the combiner function, and the argument passed to the
                 finisher function must be the result of a previous invocation of the
                 result supplier, accumulator, or combiner functions


                supplier accumulator combiner的实现结果-->
                传递给下一次supplier accumulator combiner操作
                或返还给汇聚操作的调用方
                而不进行其他操作
                The implementation should not do anything with the result of any of
                the result supplier, accumulator, or combiner functions other than to
                pass them again to the accumulator, combiner, or finisher functions,
                or return them to the caller of the reduction operation


                一个结果传递给combiner finisher而相同的对象没有从此函数中返回 这个结果不会再被使用
                这个传入结果是被消费了 生成了新的对象
                 If a result is passed to the combiner or finisher
                 function, and the same object is not returned from that function, it is
                 never used again


                一旦结果传递给combiner finisher 则不再会传递给accumulator
                说明流中元素已经传递完全  accumulator任务已执行完毕
                Once a result is passed to the combiner or finisher function, it
                is never passed to the accumulator function again

                非并发单线程
                For non-concurrent collectors, any result returned from the result
                supplier, accumulator, or combiner functions must be serially
                thread-confined.  This enables collection to occur in parallel without
                the {@code Collector} needing to implement any additional synchronization.
                The reduction implementation must manage that the input is properly
                partitioned, that partitions are processed in isolation, and combining
                happens only after accumulation is complete

                并发多线程
                For concurrent collectors, an implementation is free to (but not
                required to) implement reduction concurrently.  A concurrent reduction
                is one where the accumulator function is called concurrently from
                multiple threads, using the same concurrently-modifiable result container,
                rather than keeping the result isolated during accumulation.
                A concurrent reduction should only be applied if the collector has the
                {@link Characteristics#UNORDERED} characteristics or if the
                originating data is unordered

            */

六、Characteristics对Collectors的性能优化

            /*      Characteristics对Collectors的性能优化
             *
             *      Collectors also have a set of characteristics, that provide hints that can be used by a
             *      reduction implementation to provide better performance.
             *
             *
             *      Characteristics indicating properties of a {@code Collector}, which can
             *      be used to optimize reduction implementations.
             *
             *   enum Characteristics {
             *
                  * Indicates that this collector is <em>concurrent</em>, meaning that
                  * the result container can support the accumulator function being
                  * called concurrently with the same result container from multiple
                  * threads.
                  *
                  * If a {@code CONCURRENT} collector is not also {@code UNORDERED},
                  * then it should only be evaluated concurrently if applied to an
                  * unordered data source.

                 CONCURRENT, 多线程处理并发 一定要保证线程安全 使用无序数据源  与UNORDERED联合使用


                  * Indicates that the collection operation does not commit to preserving
                  * the encounter order of input elements.  (This might be true if the
                  * result container has no intrinsic order, such as a {@link Set}.)

                 UNORDERED,  无序集合


                  * Indicates that the finisher function is the identity function and
                  * can be elided.  If set, it must be the case that an unchecked cast
                  * from A to R will succeed.

                 IDENTITY_FINISH  强制类型转换
             }*/

七、Collector接口与 Collectors

        //     Collectors---> Collector接口简单实现  静态内部类CollectorImpl
        //     为什么要在Collectors类内部定义一个静态内部类CollectorImpl:
        //          Collectors是一个工厂、辅助类  方法的定义是静态的
        //          以类名直接调用方法的方式向developer提供最常见的Collector实现 其实现方式是CollectorImpl
        //          CollectorImpl类 有且仅有在 Collectors类 中使用 所以放在一起

八、测试方法:

        // Accumulate names into a List  将学生姓名累积成ArrayList集合
        List<String> snameList = students.stream()
                .map(Student::getName).collect(Collectors.toList());
        System.out.println("将学生姓名累积成ArrayList集合:" + snameList.getClass());
        System.out.println(snameList);
        System.out.println("-----------------------------------------\n");

        // Accumulate names into a TreeSet 将学生姓名累积成TreeSet集合
        Set<String> snameTree = students.stream()
                .map(Student::getName).collect(Collectors.toCollection(TreeSet::new));



        System.out.println("将学生姓名累积成TreeSet集合:" + snameTree.getClass());
        System.out.println(snameTree);
        System.out.println("-----------------------------------------\n");

        // Convert elements to strings and concatenate them, separated by commas  将学生姓名累积成一个Json串 以逗号分隔
        String joinedStudents = students.stream()
                .map(Student::toString).collect(Collectors.joining(","));
        System.out.println(" 将学生姓名累积成一个Json串 以逗号分隔:" + joinedStudents);
        System.out.println("-----------------------------------------\n");

        // Compute sum of salaries of students  求学生总薪水
        double totalSalary = students.stream()
                .mapToDouble(Student::getSalary).sum();
        System.out.println("学生总薪水:" + totalSalary);
        System.out.println("-----------------------------------------\n");


        // the min id of students     打印最小id的学生信息
        System.out.println("最小id的学生信息:");
        students.stream()
                .min(Comparator.comparingInt(Student::getId))
                .ifPresent(System.out::println);
        System.out.println("-----------------------------------------\n");


        // the max id of students     打印最大id的学生信息
        System.out.println("最大id的学生信息:");
        students.stream()
                .max(Comparator.comparingInt(Student::getId))
                .ifPresent(System.out::println);
        System.out.println("-----------------------------------------\n");


        // Compute avg of Age of students   求学生平均年龄
        Double avgAge = students.stream()
                .collect(Collectors.averagingInt(Student::getAge));
        System.out.println("学生平均年龄:" + avgAge);
        System.out.println("-----------------------------------------\n");


        // Compute SummaryStatistics of Age of students   打印学生年龄的汇总信息
        IntSummaryStatistics ageSummaryStatistics = students.stream()
                .collect(Collectors.summarizingInt(Student::getAge));
        System.out.println("学生年龄的汇总信息:" + ageSummaryStatistics);
        System.out.println("-----------------------------------------\n");


        //  根据性别分组 取id最小的学生
        //  直接使用Collectors.minBy返回的是Optional<Student>
        //  因能确认不为Null 使用Collectors.collectingAndThen-->Optional::get获取
        Map<String, Student> minIdStudent = students.stream().
                collect(Collectors.groupingBy(Student::getSex, Collectors.collectingAndThen
                        (Collectors.minBy(Comparator.comparingInt(Student::getId)), Optional::get)));

        System.out.println(minIdStudent);
        System.out.println("-----------------------------------------\n");

    }
}

九、测试结果

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-20 16:11:56.217  INFO 17260 --- [           main] c.j.design.java8.Stream.CollectorDetail  : Starting CollectorDetail on DESKTOP-87RMBG4 with PID 17260 (started by 46250 in E:\IdeaProjects\design)
2019-02-20 16:11:56.223  INFO 17260 --- [           main] c.j.design.java8.Stream.CollectorDetail  : No active profile set, falling back to default profiles: default
2019-02-20 16:11:56.699  INFO 17260 --- [           main] c.j.design.java8.Stream.CollectorDetail  : Started CollectorDetail in 0.678 seconds (JVM running for 1.401)
-----------------------------------------

将学生姓名累积成ArrayList集合:class java.util.ArrayList
[Kirito, Asuna, Sinon, Yuuki, Alice]
-----------------------------------------

将学生姓名累积成TreeSet集合:class java.util.TreeSet
[Alice, Asuna, Kirito, Sinon, Yuuki]
-----------------------------------------

 将学生姓名累积成一个Json串 以逗号分隔:Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8),Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8),Student(id=3, name=Sinon, sex=Female, age=16, addr=Gun Gale Online, salary=9.99999999E8),Student(id=4, name=Yuuki, sex=Female, age=15, addr=Alfheim Online, salary=9.99999999E8),Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)
-----------------------------------------

学生总薪水:4.999999995E9
-----------------------------------------

最小id的学生信息:
Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)
-----------------------------------------

最大id的学生信息:
Student(id=5, name=Alice, sex=Female, age=14, addr=Alicization, salary=9.99999999E8)
-----------------------------------------

学生平均年龄:16.0
-----------------------------------------

学生年龄的汇总信息:IntSummaryStatistics{count=5, sum=80, min=14, average=16.000000, max=18}
-----------------------------------------

{Female=Student(id=2, name=Asuna, sex=Female, age=17, addr=Sword Art Online, salary=9.99999999E8), Male=Student(id=1, name=Kirito, sex=Male, age=18, addr=Sword Art Online, salary=9.99999999E8)}
-----------------------------------------

如果你喜欢这个免费软件,请MAIL一封信以对我的支持。 Collector资料收集管理器 V4.1 Collector资料收集管理器能够把您收集的文本、网页、图片等资料都存放在一起,统一管理的绿色免费软件。 使用系统图标,支持大容量数据库,支持拖拉操作,采用视窗风格,目录树结构管理,所见即所得的设计理念,操作方便。 上网浏览网页时允许通过定制IE的右键菜单来方便收集网页、图片和文字。 本软件特色是可以直接把整个网页保存成MHT或JPG格式的文件,独特的收集网页图片模式。 本地导入速度一,比其它同类的软件都快很多(可以在网上找一个同类软件导入过万条记录比较)。 是一个非常实用的电子书制作工具;可以把数据库文件转换成可执行文件(*.exe),也可以制作成CHM文件。 您可以给书籍文件或者节点设置密码。 可以实时备份数据库,可查看修改记录,保证你的数据安全。 免费分享数据库。 附带一个例子数据库,里面有使用方法。 讨论Collector 资料收集管理器的QQ群号码 27585577 论坛 http://14500001.blog.163.com/ http://user.qzone.qq.com/14500001 V4.1版本 更新日期 2010-03-20 更新内容 1、调整菜单; 2、修正批量改节点功能; 3、添加另存数据库功能; 4、修正对实时备份数据库的判断。 更新日期 2010-01-04 更新内容 1、升级数据库版本,支持更多功能; 2、使用SQLite数据库(RTB)进行实时备份数据库,数据库(HDF)打开始加载。 2、全新界面,可改变布局和改变皮肤; 3、查询状态下可修改数据; 4、EXE电子书文件可自定义图标。 更新日期 2009-03-24 21:00:00 更新内容 1、修正新建数据库的一个问题; 2、改写保存数据库方式; 更新日期 2009-02-21 23:45:00 更新内容 1、修正不允许运行多个Collector时,程序最小化无法密码保护问题; 2、修正制作EXE电子书的一个问题; 3、添加收集网页时先对数据进行校验再导入,防止导入空数据破坏节点; 4、修正判断OFFICE是否安装的问题。 2008-10-15 16:35:00 更新内容 1、一些微小的改动 2、修正软件在数据库只读环境下导出的问题 2008-08-25 更新内容 1、添加翻页阅读; 2、添加批量改名; 3、添加闹钟提醒; 4、添加最小化到任务栏; 5、添加保存时检查索引。 2008-08-01 16:10:00 更新内容 1、修正由于空文件夹无法生成CHM电子书的问题; 2008-07-17 更新内容 1、修正导出CHM文件每个目录的连接。 2008-07-10 更新内容 1、修正判断是否安装OFFICE的问题; 2、优化收集网页(htm格式)代码。 2008-06-26 14:30:00 更新内容 1、修正收集某些网页时无法浏览的问题; 2008-06-19 14:15:00 更新内容 1、修正收集网页时某些图片无法显示问题; 2、修正收集图片排序问题; 更新日期 2008-05-09 14:00:00 更新内容 1、修正新建数据库新建文件提示密码问题; 更新日期 2008-04-24 15:30:00 更新内容 1、修正新建数据库导入本地文件提示密码问题; 2、修正无法打开只读属性文件的问题; 3、修正回收站无法导出CHM问题; 4、...... 更新日期 2008-04-16 15:00:00 更新内容 1、更换文本文件编辑,支持语法高亮显示; 2、添加网页编辑功能; 3、使用软件自身做电子书执行文件,大大减少软件大小。 4、..... 更新日期 2008-03-14 16:00:00 更新内容 1、支持OFFICE2007最新的XLSX、DOCX、PPTX格式文件。 2、添加回收站功能。 3、添加节点排序功能。 4、修正一个加密问题。 5、修正按内容搜索后,切换到编辑窗口后不能编辑。 更新日期 2008-03-04 10:30:00 更新内容 1、添加读书模式(文本类型文件); 2、添加自定义调用外部编辑器编辑功能(文本类型文件); 3、修正修改节点(文件夹)备注会损坏节点图标问题; 4、添加记忆悬浮窗位置功能; 5、修正收集图片时收集窗体无法最前端功能(IE7); 6、加快调用QQ抓图速度; 7、修改导入本地文件不是在选中节点下的问题 更新日期 2008-02-23 14:00:00 更新内容 1、修改截图,使用最新的QQ截图功能; 2、修正加载数据库时的一个问题; 3、判断是否使用OFICE2007,对OFFICE2007,不再使用IE打开方式。 更新日期 2008-02-01 15:50:00 更新内容 1、修正打开数据库CPU占用率很高的问题 2008-01-25 11:00:00 更新内容 1、添加...... 2、添加抓图到文本文件功能,保存时需要转为RTF格式。 3、修正只读打开还能添加数据的问题。 2007-12-29 1、添加书签保存、管理功能 2、修正一个损坏节点问题 3、添加编辑文本的一些功能 4、添加数据库列表功能 5、修正一些小问题 更新日期 2007-12-21 1、修正网页滚动抓图问题 更新日期 2007-12-15 1、添加最小化到托盘选项 2、添加启动显示悬浮窗选项 3、添加更改软件所在文件夹图标选项 4、添加判断导入网页路径是否重复功能 5、添加支持从网页(暂时只文本)或图片拖拉到悬浮窗保存 6、修改软件内部拖拉功能(按Ctrl或Alt和不按功能不同) 7、修改软件启动的语言为上次选择的语言 8、添加关闭程序不提示备份选项 9、添加导入TXT文件取第一行内容为标题功能 更新内容(重要提示:请及时备份数据) 2007-11-18 11:25:00 修正一个导入文件会损坏节点问题; 修正修改节点密码; 修正....... 2007-10-16 1、减少IE右键菜单(需重新创建到IE浏览器右键菜单才能生效) 2、添加收集时可编辑节点信息。 2007-10-10 15:55:00 1、添加word文件显示常用、格式工具栏及不显示审阅工具栏 2、添加Excel、PowerPoint文件显示常用、格式工具栏 2007-09-16 16:00:00 美化界面 自动提示版本更新 修正编辑文本保存的问题(之前是OK的) 2007-09-11 13:50:00 修正节点标题的复制粘贴问题 修正密码框焦点问题 修正菜单导入文件时只有exe文件的错误(之前是OK的) 2007-09-09 修正显示目录栏宽度问题; 修正自身复制监视剪贴板的问题; 修正收集网页图片的一个小问题。 V2.9 2007-09-06 17:00:00 添加调用OFFICE打开EXCEL、WORD、PowerPoint文件功能,而且修改后能自动回存到数据库。 修正浏览文本时TAB键不可用的问题。 添加最前端按钮。 添加直接调用QQ和作者交; 2007-08-24 13:25:00 添加节点有附件时图标异样显示 2007-08-15 10:50:00 修正新建一个数据库时不能新建一个目录或文件 2007-08-10 15:45:00 1、添加修改文本的一些功能。 2、修正文本状态下设标题错误问题; 2.85 1、修正在VISTA下MHT格式收集网页无内容显示问题。 2.84 1、修正在VISTA下无法使用问题。 2.83版本 1、修正一些搜索问题; 2、添加新建根目录文件菜单。 2.82版本 1、修正在搜索数据库时导入本地文件会导致节点损坏的问题; 2、加快加载数据库。 3、改删除节点快捷方式为DEL键。 2.81版本 1、修正合并数据库会导致数据库损坏的问题; 2.8版本 1、添加内嵌打开、修改、保存EXCEL、WORD、PowerPoint文件功能(需要安装OFFICE); 2、添加内嵌打开PDF文件功能(需要安装PDF软件); 3、修正繁体下的一些问题。 4、添加图片预览功能; 5、修正一个会导致数据库损坏的问题; 6、修正几个小问题。 2.7版本 1、修改下载功能,添加HTTP代理模式; 2、添加标题着色功能; 3、修改收集网页(Htm)格式方法; 4、右键收集可以选择导入当前目录; 2.6版本 1、添加下载数据库功能。 2、创建或清除快捷方式无须重新打开ie。 3、修改加载图标算法,超速打开数据库。 打开数据库后请使用修复图标功能,再次打开才能体现。 2.5版本 1、添加附件功能; 2、自定义抓图压缩率。 3、添加下载数据库功能。 4、创建或清除快捷方式无须重新打开ie。 2.4版本 1、添加最小化密码保护; 2、自定义滚动抓图刷新时间。 3、修正导出有重名的文件的问题。 4、修正查询HTM格式文件问题。 5、修正下载问题。 2.3版本 1、添加制作EXE格式电子书功能; 2、修正节点标题粘贴问题。 3、修正合并2.2版本数据库HTM格式的文件无法浏览的情况。 4、修改TXT文件被修改转为RTF的提示。 .... 2.2版本 1、修改保存网页HTM方式; 2、添加选择多张图片保存成HTM方式; 3、添加简单的图像编辑功能; 4、修改数据库结构(打开旧版本数据库会自动转换),添加文件备注; 注意:新版本数据库不能使用旧版本软件打开。 5、添加收集网页时自动保存功能; 6、...... 2.1版本 1、修改抓图方式,改为调用QQ链接库抓图(无需安装QQ); 2、修正在2003下抓网页为JPG图片不全问题; 3、修正在XP下导入网页图片节点添加问题; 4、搜索状态下添加导出功能; 5、添加数据库所在磁盘空间不足时导入过多数据提示; 6、修改在线升级; 7、添加节点手动排序; 8、加大悬浮窗口; 9、标题栏可以使用系统右键菜单(剪切粘贴复制); 10、在菜单中添加书签功能; 11、在菜单中添加导入功能; 12、添加清除软件在系统中的所有痕迹功能; 2.0版本 1、修正在WIN98下程序在根目录运行出错的问题; 2、修正在繁体系统下语言版本的问题; 3、添加在文档中插入图片和插入附件功能; 4、添加在线升级功能; 5、添加重要更能:支持所有文件类型; 6、添加自定义热键功能; 7、添加多种选项把保存网页成图片。 8、修改抓图模式。 9、修正一些错误。 1.9版本 1、添加导出数据生成程序数据库HDF格式功能。 2、修正合并数据库没有考虑到合并的数据库密码问题; 3、修正旧版本选择不压缩的数据库转为新版本的数据库浏览时数据出错的问题。 4、把hha.dll和hhc.exe这两个文件打包进执行文件。 5、添加制作CHM文件选项。 6、美化菜单; 使用技巧 1、务必要看例子数据库的使用方法。 2、浏览网页如果乱码,请取消使用浏览,IE5.0版本不支持MHT文件格式请使用IE5.5或以上版本。 3、最小化可以双击右下角的图标来显示主窗体。 4、收集网页数据时最好先把一个数据库关联到我的最爱,这样就可以在软件没有运行的状态下点击IE右键菜单直接启动软件导进设好的数据库里面,无须先启动软件。注意:软件可以同时运行多个,收集网页时请只运行一个。 5、如果你想修改左边目录文件的标题,可以把在右边选中的文字拖拉过去就行了,文本网页都可以。 6、请经常备份数据库。 7、如果没有图片的网页不推荐保存成MHT格式,因为MHT格式文件大,而且打开耗内存(这是IE的问题)。 8、如果你删除了脚本文件,请重新创建IE快捷方式。 1.8版本 1、添加合并数据库功能; 2、添加是否允许运行多个程序功能; 3、添加选择压缩方式功能; 4、优化内存使用; 5、修正从菜单功能中导进文件数据对不上的问题; 6、修正添加无内容文件时的BUG; 7、添加只读打开功能(要设置密码); 1.7版本 1、修改数据库格式,添加一些数据库信息,程序会把旧数据库自动转换到新版本的数据库格式,在同目录下面有后缀名为OLD的原数据库的备份文件,以防万一出错。 2、新版本已经把Collector.ini放到可执行文件的当前目录,而且新版本还有一个language文件夹和desktop.ini、Collector.ico两个文件。 3、添加清除本软件在注册表的信息,如果你不想用本软件可以选中清除软件痕迹菜单。 4、添加生成CHM格式功能(需要把hha.dll和hhc.exe这两个文件放在和Cellector.exe同一目录) 5、添加记录导进文件的路径功能。 6、添加书签功能,没有限制书签数目,搜索时也可以使用。 7、添加导入和其它一些菜单。 8、添加一些小功能和修正一些错误。 在例子数据库里添加了生成CHM文件和把网页抓图保存成JPG文件的源代码,希望各位指点。 1.6版本 1、添加浏览网页时把网页抓图保存成JPG文件功能(针对单框架网页); 2、添加设定数据库密码功能; 3、添加热键抓图功能(ALT+A); 4、添加最小化窗体或显示功能(ALT+Z); 5、修正把大网页保存成MHT文件出错的问题; 1.5版本 1、添加浏览网页时放大网页功能; 2、修正由于输入法引起的一个错误; 3、优化收集网页代码,改为直接使用内存,加快导入速度。 1.4版本 1、重写使用IE右键收集网页的代码,能很好的收集网页(可以和其它软件对比看看结果),大大加强了IE收集功能, 2、添加把网页保存成文本功能, 3、添加支持RTF文件, 4、添加备份数据功能, 5、大幅度提高了打开数据库的速度, 6、修正了一次性导进超过5万条记录出错的BUG, 注意:1.4版本IE收集功能改变太大,如果使用了之前的版本 第一,删除Collector.exe根目录下面的*.htm文件,替换使用新版本的Collector.exe文件。 第,手工删除IE右键带☆号的菜单(使用其它软件),运行本程序再重新创建IE右键菜单。  默认支持以下类型 .HTM;.HTML;.HTX;.HTW;.MHT;.MHTML;.SHTML;.XML;.EML;.SWF;.PHP;.TXT;.RTF;.JPEG;.JPG;.GIF;.BMP;.TIFF;.PCX;.ICO;.CUR;.PNG;.WMF;.EMF;.TGA;.PXM;.TIF;.XIF;.JPE;.JIF;.JFIF;.DCX;.ANI;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值