如何通过通配符通用迭代?

我怎么可以遍历一个通配符通用? 基本上我想内联下面的方法:

private <T extends Fact> void iterateFacts(FactManager<T> factManager) { for (T fact : factManager) { factManager.doSomething(fact); } }

如果该码是在一个单独的方法如所示,它的工作原理是因为通用方法上下文允许定义通配符类型(这里T )在其上可以进行迭代。 如果有人试图内联此方法,该方法的上下文消失了,没有人可以遍历一个通配符类型了。 即使在Eclipse将自动执行此操作失败,出现以下(不可编译)代码:

... for (FactManager<?> factManager : factManagers) { ... for ( fact : factManager) { factManager.doSomething(fact); } ... } ...

我的问题很简单:有没有把一些通配符类型可以迭代的方式,或者这是仿制药的限制(这意味着它是不可能这样做)?

--------------解决方案-------------

类型参数只能在定义

  • 类型(即类/接口),
  • 方法,以及
  • 构造函数。

就需要一个类型参数为一个局部块,这是不可能的。

是啊,我错过了这样的事情有时候,太。

但是,是不是真的与具有方法在这里非内联的一个问题 - 如果它提出了一个性能瓶颈,其中内联会有所帮助,热点再次将它内联(不关心的类型)。

此外,具有一个单独的方法可以给它一个描述性名称。


只是一个想法,如果你需要这往往:

interface DoWithFM {
void <T> run(FactManager<T> t);
}

...
for (FactManager<?> factManager : factManagers) {
...
new DoWithFM() { public <T> run(FactManager<T> factManager) {
for (T fact : factManager) {
factManager.doSomething(fact);
}
}.run(factManager);
...
}
...

否。在这样的情况下,解决办法是建立一个辅助方法。

该JLS有这个例子http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.10

public static void reverse(List<?> list) { rev(list);}
private static <T> void rev(List<T> list) { ... }

问题是,我们有一个List<?>对象。 我们知道,它必须是一个List<X>的一些X ,我们想利用编写代码X 。 内部编译器通配符转换为一个类型的变量X ,但是Java语言不提供程序员直接的方式来访问它。 但如果有接受的方法List<T>我们可以将对象传递给方法。 编译器推断T=X和呼叫好。

如果没有类型擦除, X可以在运行时已知的,那么Java肯定给大家一个办法来访问X 。 然而今天,因为X是不是在运行时可用,没有多少点。 可以提供纯合成的方法,这是不可能比辅助方法解决方法简单。

好吧,我可以想办法用内部类做,因为内部类股与它的封闭类型的类型参数。 此外,即使使用通配符你仍然可以处理您的收藏感谢通配符捕获转换。

让我创建一​​个例子。 此代码编译并运行正常。 但我不能肯定如果采用内部类的会是你的问题。

//as you can see type parameter belongs to the enclosing class
public class FactManager<T> implements Iterable<FactManager<T>.Fact> {

private Collection<Fact> items = new ArrayList<Fact>();

public void doSomething(Fact fact) {
System.out.println(fact.getValue());
}

public void addFact(T value) {
this.items.add(new Fact(value));
}

@Override
public Iterator<Fact> iterator() {
return items.iterator();
}

public class Fact {
//inner class share its enclosing class type parameter
private T value;

public Fact(T value) {
this.value = value;
}

public T getValue() {
return this.value;
}

public void setValue(T value) {
this.value = value;
}
}

public static void main(String[] args) {
List<FactManager<String>> factManagers = new ArrayList<FactManager<String>>();

factManagers.add(new FactManager<String>());
factManagers.get(0).addFact("Obi-wan");
factManagers.get(0).addFact("Skywalker");

for(FactManager<? extends CharSequence> factManager : factManagers){
//process thanks to wildcard capture conversion
procesFactManager(factManager);
}
}

//Wildcard capture conversion can be used to process wildcard-based collections
public static <T> void procesFactManager(FactManager<T> factManager){
for(FactManager<T>.Fact fact : factManager){
factManager.doSomething(fact);
}
}
}

您可以随时退回到Object

for (FactManager<?> factManager : factManagers) {
...
for ( Object fact : factManager) {
factManager.doSomething(fact);
}
...
}

这当然是受什么是实际申报doSomething

如果doSomething声明为这个void doSomething( T fact ) ,那么在这里你的追索权将是使用原始类型和吞咽unchecked警告。 如果你能保证FactManager只能有均匀的Facts插入,那么这可能是一个确定的解决方案。

for (FactManager factManager : factManagers) { // unchecked warning on this line
...
for ( Object fact : factManager) {
factManager.doSomething(fact);
}
...
}

这是更精确地匹配到你定义的方法(也就是,如果你可以调用iterateFacts()与FactManagers在factManagers,你知道FactManager包含是事实的一些子类项目)。

for (FactManager<? extends Fact> factManager : factManagers) {
for (Fact fact : factManager) {
factManager.doSomething(fact);
}
}

我倾向于但是认为,你将宣布FactManager是通用对事实的亚型(刚才的类的名称),例如:

class FactManager<T extends Fact> implements Iterable<T> {
...
}

因为它不能推断由包含一个对象的类型在Eclipse重构失败FactManager<?>

分类:java的 时间:2012-01-01 人气:0
本文关键词: Java中,泛型的foreach
分享到:

相关文章

  • 在Java中循环和foreach循环PHP中的型差分 2015-02-10

    在PHP中,我们使用.... foreach ($array as $value) { echo $value; } 在Java中可以使用做同样的事情 for (int e : array) { System.out.println(e); } 有上述2代码段之间的任何差异 --------------解决方案------------- 这是非常接近的东西两种形式的java的for-each迭代器(数字和Iterator)做的,但是PHP迭代器也可以提供密钥和通过引用结合迭代值,所以你可以,如果

  • LinkedList的实现在Java中泛型和增强的for 2012-04-08

    我需要你来检阅我实现一个单向链表(SLL)请的. 实施应​​该使用泛型,并能使用增强的. 问题是,当我做for (Number n : list)是list一个MyLinkedList<Integer>或MyLinkedList<Double>我得到的错误:"类型不匹配:不能从元素类型的对象转换为数字". 这就是我. 我不是很确定有关的部分是仿制药和迭代器. 提前致谢. import java.util.Iterator; public class MyLink

  • 在Java中的.NET Lambda表达式 2014-05-13

    近日笔者从C#移动到Java [再次]. 但是我很喜欢怀念lambda表达式之类的C#IEnumerable.Foreach. 所以我要寻找在Java中的lambda表达式库. 有没有比LambdaJ更好的库? 也就是Clojure的Java程序可以内联直接? 这是我可以在Java功能的混合使用Clojure的代码? --------------解决方案------------- Java的8可能有拉姆达支持原生. 在那之前,你可以使用像谷歌,番石榴匿名内部类和库的组合. 以下是你可以看看其他图

  • 是否有任何替代在Java可能对应的​​foreach存在于其他一些语言如C# 2014-06-24

    有没有在Java中的任何替代方案,可能对应foreach{}在其他语言如C#或VB或类似的语言吗? 它有时,在一些非常特殊的情况下是非常有用的,几乎是强制性的. 可以在以下while(){}环在Java中具有的foreach循环或可以在Java中存在并对应于FOREACH一些其他概念取代? public class Demo { public static void main(String[] args) { ArrayList<String> arrayList = new ArrayLis

  • 有一个参数,我可以在Java中使用所有的for-each循环的作品? 2013-11-25

    假设我有一个接受一个数组,它使用Java内置的for-each循环,这样在处理每一个元素的方法: public static void myFun(SomeClass[] arr) { for (SomeClass sc : arr) { // Stuff is processed here } } 这工作得很好,但现在我希望能够通过同样的方法List<SomeClass>代替. 难道我注定要使用Collection.toArray(T []),或者是有一个参数,我可以使用myFun()接受任

  • 我如何克隆在Java中的泛型列表? 2012-01-14

    我有一个ArrayList<String> ,我想返回一个副本ArrayList有一个克隆方法具有以下签名: public Object clone() 之后我把这种方法,我怎么投返回的对象回ArrayList<String> ? --------------解决方案------------- ArrayList newArrayList = (ArrayList) oldArrayList.clone(); 为什么要克隆? 创建一个新的列表,通常会更有意义. List<St

  • 解决泛型方法,在Java的泛型参数类型像在C#中? 2012-09-08

    如何检查Java中的泛型参数的类型(不使用反射,如果可能的话)? 我们的目标是像C#允许这样做: public <T> void doStaff() { if(T is Type1) { } if(T is Type2) { } } 如何写一样,在Java中的方法? --------------解决方案------------- 在Java的泛型信息将被删除在运行时. 你永远不能做这样的事"T的instanceof". 但是,你可以通过一些东西到方法,并做一个instanc

  • 我可以使用Java泛型有相同接口的不同实现在Java中? 2012-10-02

    假设我想一个类转换成另一种使用泛型. 我能做到这一点? 对于如. Class BConvertImpl implements Converter { A toA(Class B); void update(Class A, Class B); } Class CConverterImpl implements Converter { A toA(Class C); void update(Class A, Class C); } 我可以使用泛型来实现这一点? 我非常新的泛型在Java中. 有人可

  • 我可以使用Java中嵌套泛型? 2012-10-09

    我试图做这样的事情: public class MyClass <A, B, C <A, B> > { ... } 但是Eclipse突出"B",并说"意外,预计延伸". 怎么办? 嵌套泛型不允许? --------------解决方案------------- 那是因为你还没有定义C作为本身与2型参数类型的一种类型. 尝试是这样的: public class MyClass <A, B, C extends Map<A, B&g

  • 如何做PHP爆炸(“”),在Java中样式列表()的foreach() 2012-12-11

    我有PHP代码,我将其转换成Java,但是我们怎么办PHP​​像爆炸(),表()的foreach()与Java? 下面的PHP代码是我的问题,例如: 1. PHP: /** * @return: Array */ public function parse($digest) { $array = array(); $parts = explode(", ", $digest); foreach ($parts as $x) { $bits = explode("="

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 1.060 (s). 10 q(s)