我需要使用Java逐行读取大约5-6 GB的大文本文件.
我该怎么办?
对于Java语言有些新意,我试图让自己熟悉一个可能遍历列表(或者可能是其他集合)以及每个集合的优点或缺点的所有方法(或者至少是非病态方法).
给定一个List<E> list对象,我知道以下循环所有元素的方法:
while/ do while循环以及)// Not recommended (see below)!
for (int i = 0; i < list.size(); i++) {
    E element = list.get(i);
    // 1 - can call methods of element
    // 2 - can use 'i' to make index-based calls to methods of list
    // ...
}
注意:正如@amarseillan指出的那样,这种形式对于迭代Lists来说是一个糟糕的选择,因为该get方法的实际实现可能不如使用时那样有效Iterator.例如,LinkedList实现必须遍历i之前的所有元素以获得第i个元素.
在上面的例子中,List实现没有办法"保存它的位置"以使未来的迭代更有效.因为ArrayList它并不重要,因为复杂性/成本get是恒定时间(O(1)),而a LinkedList是它与列表的大小(O(n))成比例.
有关内置Collections实现的计算复杂性的更多信息,请查看此问题 …
我知道如何创建对具有String参数并返回一个方法的方法的引用int,它是:
Function<String, Integer>
但是,如果函数抛出异常,这不起作用,比如说定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个参考?
据我所知.stream(),我可以使用链操作.filter()或使用并行流.但是如果我需要执行小操作(例如,打印列表的元素),它们之间的区别是什么?
collection.stream().forEach(System.out::println);
collection.forEach(System.out::println);
如何从Java 8流/ lambdas中抛出CHECKED异常?
换句话说,我想像这样编译代码:
public List<Class> getClasses() throws ClassNotFoundException {     
    List<Class> classes = 
        Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
              .map(className -> Class.forName(className))
              .collect(Collectors.toList());                  
    return classes;
    }
此代码无法编译,因为Class.forName()上面的方法抛出ClassNotFoundException,检查.
请注意我不希望将已检查的异常包装在运行时异常中,而是抛出包装的未经检查的异常.我想抛出已检查的异常本身,而不是向流添加丑陋的try/ catches.
在Java 8中,我们有Stream <T>类,它奇怪地有一个方法
Iterator<T> iterator()
所以你会期望它实现接口Iterable <T>,这需要完全这个方法,但事实并非如此.
当我想使用foreach循环遍历Stream时,我必须做类似的事情
public static Iterable<T> getIterable(Stream<T> s) {
    return new Iterable<T> {
        @Override
        public Iterator<T> iterator() {
            return s.iterator();
        }
    };
}
for (T element : getIterable(s)) { ... }
我在这里错过了什么吗?
我在尝试Java 8的Lambda表达式时遇到了问题.通常它工作正常,但现在我有方法可以抛出IOException.最好看一下以下代码:
class Bank{
    ....
    public Set<String> getActiveAccountNumbers() throws IOException {
        Stream<Account> s =  accounts.values().stream();
        s = s.filter(a -> a.isActive());
        Stream<String> ss = s.map(a -> a.getNumber());
        return ss.collect(Collectors.toSet());
    }
    ....
}
interface Account{
    ....
    boolean isActive() throws IOException;
    String getNumber() throws IOException;
    ....
}
问题是,它不能编译,因为我必须捕获isActive-和getNumber-Methods的可能例外.但即使我明确使用如下所示的try-catch-Block,它仍然无法编译,因为我没有捕获异常.所以要么JDK中存在错误,要么我不知道如何捕获这些异常.
class Bank{
    ....
    //Doesn't compile either
    public Set<String> getActiveAccountNumbers() throws IOException {
        try{
            Stream<Account> s =  accounts.values().stream();
            s = s.filter(a -> a.isActive());
            Stream<String> ss = s.map(a -> a.getNumber());
            return ss.collect(Collectors.toSet());
        }catch(IOException ex){
        } …现在,我有一个包含一段代码的程序,如下所示:
while (arrayList.iterator().hasNext()) {
     //value is equal to a String value
     if( arrayList.iterator().next().equals(value)) {
          // do something 
     }
}
我是否正确,只要迭代ArrayList就可以了?
我得到的错误是:
java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.get(Unknown Source)
    at main1.endElement(main1.java:244)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at main1.traverse(main1.java:73)
    at main1.traverse(main1.java:102)
    at main1.traverse(main1.java:102)
    at main1.main(main1.java:404)
我会显示其余的代码,但它非常广泛,如果我没有正确地进行迭代,我会假设唯一的可能性是我没有ArrayList正确初始化.
鉴于如下的流{ 0, 1, 2, 3, 4 },
我怎样才能最优雅地将其转换为给定的形式:
{ new Pair(0, 1), new Pair(1, 2), new Pair(2, 3), new Pair(3, 4) } 
(假设,当然,我已经定义了类对)?
编辑:这不是严格关于整数或原始流.对于任何类型的流,答案应该是通用的.
我正在使用Java 8中的新lambda特性,并发现Java 8提供的实践非常有用.但是,我想知道是否有一种很好的方法可以解决以下情况.假设您有一个对象池包装器,需要某种工厂来填充对象池,例如(使用java.lang.functions.Factory):
public class JdbcConnectionPool extends ObjectPool<Connection> {
    public ConnectionPool(int maxConnections, String url) {
        super(new Factory<Connection>() {
            @Override
            public Connection make() {
                try {
                    return DriverManager.getConnection(url);
                } catch ( SQLException ex ) {
                    throw new RuntimeException(ex);
                }
            }
        }, maxConnections);
    }
}
将函数接口转换为lambda表达式后,上面的代码变为:
public class JdbcConnectionPool extends ObjectPool<Connection> {
    public ConnectionPool(int maxConnections, String url) {
        super(() -> {
            try {
                return DriverManager.getConnection(url);
            } catch ( SQLException ex ) {
                throw new RuntimeException(ex);
            }
        }, maxConnections); …java ×10
java-8 ×7
java-stream ×4
lambda ×4
collections ×2
arraylist ×1
file-io ×1
io ×1
iterable ×1
iteration ×1
iterator ×1
loops ×1
performance ×1