以下代码(在android中运行)总是在第3行给出一个ClassCastException:
final String[] v1 = i18nCategory.translation.get(id);
final ArrayList<String> v2 = new ArrayList<String>(Arrays.asList(v1));
String[] v3 = (String[])v2.toArray();
Run Code Online (Sandbox Code Playgroud)
它也发生在v2是Object [0]时,以及当它中有字符串时.任何想法为什么?
我只是看看List界面中定义的方法:<T> T[] toArray(T[] a)
我有一个问题.为什么它是通用的?因此,方法不完全是类型安全的.以下代码片段编译但导致ArrayStoreException:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
String[] stringArray = list.toArray(new String[]{});
Run Code Online (Sandbox Code Playgroud)
在我看来,如果toArray不是通用的并采用List类型参数,那就更好了.
我已经写过玩具示例,它可以通用:
package test;
import java.util.Arrays;
public class TestGenerics<E> {
private Object[] elementData = new Object[10];
private int size = 0;
public void add(E e) {
elementData[size++] = e;
}
@SuppressWarnings("unchecked")
//I took this code from ArrayList but it is not generic
public E[] toArray(E[] a) {
if (a.length < size)
// Make a new array of a's runtime type, …Run Code Online (Sandbox Code Playgroud) 我有一个List集合,我想在多线程应用程序中迭代它.我需要在每次迭代时保护它,因为它可以被更改,而且当我做foreach时我不希望"收集被修改"异常.
这样做的正确方法是什么?
每次访问或循环时都使用锁定.我很害怕死锁.也许我只是偏执使用锁而不应该.如果我走这条路以避免死锁,我需要知道什么?锁是否相当有效?
每次我执行foreach时,使用List <>.ToArray()复制到数组.这会导致性能下降,但很容易做到.我担心内存颠簸以及复制它的时间.看起来过分了.使用ToArray是否安全?
不要使用foreach而是使用for循环.每次我这样做以确保列表没有缩小时,我不需要进行长度检查吗?这看起来很烦人.
我正在寻找一种简单的方法来克隆一个IEnumerable<T>参数供以后参考.LINQ的ToArray扩展方法似乎是一种很好,简洁的方法.
但是,我不清楚它是否总能保证返回一个新的数组实例.一些LINQ方法将检查可枚举的实际类型,并尽可能检查快捷方式; 例如,Count()将查看该方法是否实现ICollection<T>,如果是,将直接读取其Count属性; 如果必须,它只迭代集合.
鉴于实际上存在短路的心态,似乎如果我调用ToArray()已经是数组的东西,ToArray()可能会短路并简单地返回相同的数组实例.这在技术上可以满足ToArray方法的要求.
从快速测试看来,在.NET 4.0中,调用ToArray()数组确实会返回一个新实例.我的问题是,我能依靠这个吗?我是否可以保证ToArray始终返回一个新实例,即使在Silverlight和.NET Framework的未来版本中也是如此?在这一点上是否有明确的文件?
在Java泛型之前,Collection.toArray()无法知道开发人员期望的数组类型(特别是对于空集合).据我了解,这是成语背后的主要理由collection.toArray(new E[0]).
使用泛型,Collection<E>.toArray()只能返回一个充满实例E和/或其特化的数组.我想知道为什么返回类型仍然Object[]不是E[].在我看来,返回一个E[]而不是不Object[]应该破坏现有的代码.
请参阅:Collection.toArray(),Collection.toArray(T[])以及相关主题的java:(字符串[])List.toArray()给出ClassCastException异常
我只是在查看List接口中定义的方法:
以正确的顺序返回包含此列表中所有元素的数组; 返回数组的运行时类型是指定数组的运行时类型.如果列表适合指定的数组,则返回其中.否则,将使用指定数组的运行时类型和此列表的大小分配新数组.如果列表适合指定的数组,并且空间足够(即,数组的元素多于列表),则紧跟集合结尾的数组中的元素将设置为null.仅当调用者知道列表不包含任何null元素时,这在确定列表长度时很有用.
Run Code Online (Sandbox Code Playgroud)<T> T[] toArray(T[] a);
而我只是想知道为什么它以这种方式实现,基本上如果你传递一个长度为<listTeize()的数组,它只会创建一个新的并返回它.因此,在方法参数中创建新的Array对象是没用的.
另外,如果你使用列表的大小传递一个足够长的数组,如果返回与对象相同的对象 - 返回它真的没有意义,因为它是同一个对象但是为了清晰起见.
问题是我认为这会促使代码效率稍低,在我看来,Array应该只是接收类并只返回带有内容的新数组.
有没有理由说它没有这样编码?
我正在使用Codingbat网站,特别是AP-1中的这种方法
public String[] wordsWithout(String[] words, String target) {
ArrayList<String> al = new ArrayList<>(Arrays.asList(words));
al.removeIf(s -> s.equals(target));
return al.toArray(new String[al.size()]);
}
Run Code Online (Sandbox Code Playgroud)
这个实现工作,以及它当前提交的内容,但是当我将return语句更改为
return al.toArray(String[]::new);
Run Code Online (Sandbox Code Playgroud)
据我所知,这应该工作,给出以下错误:
no suitable method found for toArray((size)->ne[...]size])
method java.util.Collection.<T>toArray(T[]) is not applicable
(cannot infer type-variable(s) T
(argument mismatch; Array is not a functional interface))
method java.util.List.<T>toArray(T[]) is not applicable
(cannot infer type-variable(s) T
(argument mismatch; Array is not a functional interface))
method java.util.AbstractCollection.<T>toArray(T[]) is not applicable
(cannot infer type-variable(s) T
(argument mismatch; Array is not …Run Code Online (Sandbox Code Playgroud) 我注意到在向查询添加.ToArray()或.ToList()时,数据库查询运行得更快.这是因为数据集被加载到内存中,所有后续查询都是在内存中完成而不是进行进一步昂贵的数据库调用吗?
对于数据库查询的内存存储应该有什么限制,因为我担心耗尽太多的内部内存会降低整个项目的速度,因为我确信占用过多的内存存储会大大减慢速度.
编辑:这是为Linq-SQL查询.我正在使用SQL Server 2008.
示例1:执行大型数据库查询并在内存中过滤
我有一个包含5 000行的数据库表.我查询整个表(例如SELECT*From Clients).我接下来的几个查询基于上一个查询中的字段:a)获取所有男性客户; b)获取所有女性客户c)获取FirstName以A开头的所有客户端.
示例2:执行更频繁的数据库调用
使用具有5000行的相同Client表,我需要执行3个查询a)获取所有男性客户端; b)获取所有女性客户端c)获取FirstName以A开头的所有客户端.我通过数据库调用而不是内存来执行所有查询.
哪种方法更有效?
在下面的代码中,我需要从toSearch中获取元素,任何元素.我无法在Set接口定义中找到有用的方法来返回该集合的单个(随机,但不是必需的随机)成员.所以,我使用了toArray()[0]技术(见下面的代码).
private Set<Coordinate> floodFill(Value value, Coordinate coordinateStart)
{
Set<Coordinate> result = new LinkedHashSet<Coordinate>();
Set<Coordinate> toSearch = new LinkedHashSet<Coordinate>();
toSearch.add(coordinateStart);
while (toSearch.size() > 0)
{
Coordinate coordinate = (Coordinate)toSearch.toArray()[0];
result.add(coordinate);
toSearch.remove(coordinate);
for (Coordinate coordinateAdjacent: getAdjacentCoordinates(coordinate))
{
if (this.query.getCoordinateValue(coordinateAdjacent) == value)
{
if (!result.contains(coordinateAdjacent))
{
toSearch.add(coordinateAdjacent);
}
}
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我所讨论的另一种技术是用" toSearch.iterator().next() " 替换" (Coordinate)toSearch.toArray()[0] ".哪种技术toArray()或iterator()最有可能以最少的GC(垃圾收集)影响执行最快?
我的直觉(在编写这个问题之后)是使用迭代器的第二种技术将更快地执行并且降低GC的开销.鉴于我不知道传递的Set的实现(最可能假设HashSet或LinkedHashSet),每个toArray()或iterator()方法会产生多少开销?任何有关这方面的见解将不胜感激.
问题(从上面重复):
我一直在学习如何使用java进行编程,而且我没有对LinkedLists toArray(T[] a)和toArray()方法的区别做出任何明确的解释.第二个只是将LinkedList对象中的所有元素作为数组返回,对吧?但是,第一个怎么样?
编辑:
我的意思是,我从oracle阅读文档,它说:
以适当的顺序返回包含此列表中所有元素的数组(从第一个元素到最后一个元素); 返回数组的运行时类型是指定数组的运行时类型.如果列表适合指定的数组,则返回其中.否则,将使用指定数组的运行时类型和此列表的大小分配新数组.如果列表适合指定的数组,并且空间足够(即,数组的元素多于列表),则紧跟在列表末尾的数组中的元素将设置为null.(仅当调用者知道列表不包含任何null元素时,这在确定列表长度时很有用.)
与toArray()方法一样,此方法充当基于数组的API和基于集合的API之间的桥梁.此外,该方法允许精确控制输出阵列的运行时类型,并且在某些情况下可以用于节省分配成本.
我不明白以粗体显示的句子的含义.