我有一个以下形式的Java类:
class Example {
private byte[][] data;
public Example(int s) { data = new byte[s][s]; }
public byte getter(int x, int y) { return byte[x][y]; }
public void setter(int x, int y, byte z) { byte[x][y] = z; }
}
我希望能够使用像这样的迭代器外部迭代私有数据:
for(byte b : Example) { ;/* do stuff */ }
我试图实现一个私有的Iterator类,但我遇到了问题:
private class ExampleIterator implements Iterator {
private int curr_x;
private int curr_y;
public ExampleIterator() { curr_x=0; curr_y=-1; }
public boolean hasNext() {
return curr_x != field.length-1
&& curr_y != field.length-1; //is not the last cell?
}
public byte next() { // <-- Error is here:
// Wants to change return type to Object
// Won't compile!
if(curr_y=field.length) { ++curr_x; curr_y=0; }
return field[curr_x][curr_y];
}
public void remove() { ; } //does nothing
}
如何为原始类型(非泛型)实现外部迭代器?这在Java中是否可行?
答案 0 :(得分:8)
迭代器无法生成基本类型的值。但是,它可以产生包装类型Byte
的值。这些值可以是auto-unboxed到byte
(只要它们不是null
)。
private class ExampleIterator implements Iterator<Byte> {
public boolean hasNext() { ... }
public Byte next() { ... }
}
然后你可以像这样使用它:
for (byte b : example) { ... }
答案 1 :(得分:6)
Java 8引入了primitive iterators,允许您在int,long和double集合的迭代过程中避免装箱/取消装箱。
您可以使用类型安全地实现通用PrimitiveIterator
来创建byte
PrimitiveIterator<Byte,ByteConsumer>
个ByteConsumer
。 PrimitiveIterator.ofByte
也将被实施。两者都非常简单。
为什么jdk中没有#define _WIN32_IE 0x0501
#define _WIN32_WINNT 0x0501
#define WINVER 0x0510
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
#include <dwmapi.h>
#include <gdiplus.h>
#include <wingdi.h>
using namespace Gdiplus;
HINSTANCE hInst;
// BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF
HBITMAP mLoadImageFile(wchar_t *filename)
{
HBITMAP result = NULL;
Bitmap bitmap(filename, false);
Color colBkg(0,0,0,0);
bitmap.GetHBITMAP(colBkg, &result);
return result;
}
HBITMAP zCreateDibSection(HDC hdc, int width, int height, int bitCount)
{
BITMAPINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = width;
bi.bmiHeader.biHeight = height;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = bitCount;
bi.bmiHeader.biCompression = BI_RGB;
return CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, 0,0,0);
}
HRESULT ExtendGlassIntoClient(HWND hwnd, int left, int right, int top, int bottom)
{
MARGINS margins = {left,right,top,bottom};
HRESULT hr = S_OK;
hr = DwmExtendFrameIntoClientArea(hwnd,&margins);
if (SUCCEEDED(hr))
{
// ...
}
return hr;
}
HBITMAP mImg, mStackOverflowBitmap;
HDC memDC, memDC2;
HBITMAP oldBmp, oldBmp2;
LRESULT CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
ExtendGlassIntoClient(hwndDlg, 0,0,50,0);
mImg = mLoadImageFile(L"girl.png");
mStackOverflowBitmap = zCreateDibSection(NULL, 200, 50, 32);
memDC = CreateCompatibleDC(NULL);
memDC2 = CreateCompatibleDC(NULL);
oldBmp = (HBITMAP)SelectObject(memDC, mImg);
oldBmp2 = (HBITMAP)SelectObject(memDC2, mStackOverflowBitmap);
// ** DOESNT WORK ** - produces a washed-out pink rectangle *****
// HBRUSH mBrush = CreateSolidBrush( RGB(128,0,255) );
// RECT mRect = {0,0,200,50};
// FillRect(memDC2, &mRect, mBrush);
// DeleteObject(mBrush);
Color mCol(255,128,0,255);
SolidBrush mBrush(mCol);
Graphics graphics(memDC2);
graphics.FillRectangle(&mBrush, (int)0, (int)0, 200, 50);
}
return TRUE;
case WM_ERASEBKGND:
{
HDC hdc;
RECT mRect, topRect;
hdc = (HDC)wParam;
GetClientRect(hwndDlg, &mRect);
topRect = mRect;
topRect.bottom = 50;
FillRect(hdc, &topRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
mRect.top += 50;
FillRect(hdc, &mRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
AlphaBlend(hdc, 0,0, 55,96, memDC, 0, 0, 55,96, bf);
AlphaBlend(hdc, 100,32,200,50, memDC2, 0,0,200,50, bf);
return 1;
}
case WM_CLOSE:
{
EndDialog(hwndDlg, 0);
}
return TRUE;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
}
}
return TRUE;
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
hInst=hInstance;
InitCommonControls();
int retVal = DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
GdiplusShutdown(gdiplusToken);
return retVal;
}
?可能是因为机器字大小,通常不小于int。或者字节迭代器最好由流等完成。
答案 2 :(得分:1)
您不能将泛型与基元一起使用,因为泛型需要类型的类。
你可以做的是迭代Wrapper类型(整数,字节,布尔等)......
答案 3 :(得分:0)
实现Iterable,并返回Byte对象而不是字节原语:
class Example implements Iterable<Byte> {
..
public Iterator<Byte> iterator() {
return new MyIterator();
}
private class MyIterator implements Iterator<Byte> {
public Byte next() {...}
....
}
}
实现Iterable而不是Iterator允许您使用for-each循环直接循环对象项。
答案 4 :(得分:0)
如果您希望迭代器实现java.util.Iterator,那么next()必须返回Byte
class ByteArrayIterator implements Iterator<Byte> {
final byte[] a;
int i = 0;
ByteArrayIterator(byte[] a) {
this.a = a;
}
public boolean hasNext() {
return i < a.length;
}
public Byte next() {
if (i == a.length) {
throw new NoSuchElementException();
}
return a[i++];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
删除也可以实现。如果你不需要它实现Iterator,那么我们可以改变next()来返回字节
class ByteArrayIterator {
...
public byte next() {
if (i == a.length) {
throw new NoSuchElementException();
}
return a[i++];
}