I'm searching for this problem since days and I can't seem to find a proper answer.
So I have an ArrayList of Arrays in form of Objects (ArrayList) filled with the result set of a SQL string. My goal is to convert the result of only one row into a one-dimensional Array of Objects.
I have tried several times my research results from this website, but the only knowledge I've made was how to convert a one-dimensional ArrayList to a simple array.
I hope you guys can help me in some ways. Thanks!
My table is looking like this:
sizeid | diameter
1 | 32
2 | 40
With the SQL-command "SELECT diameter FROM size" I'll get those two numbers 32 and 40, stored in a simple 2x1 table.
| 32 |
| 40 |
Now I want to have them in a one-dimensional Array.
the method to convert:
private Object[] getSizes() {
query = new SQLquery();
query.setSQLstring("SELECT diameter FROM size");
query.runQuery();
List<Object> sizeList = query.getRowData();
Object[] sizes = new Object[sizeList.size()];
// here I want to convert the List to an array..
return sizes;
}
the method to generate the ArrayList of the class SQLquery:
public void outputResult() {
try {
if (result != null) {
ResultSetMetaData meta = result.getMetaData();
columns = meta.getColumnCount();
columnNames = new Object[columns];
for (int i=1; i<=columnNames.length; i++) {
columnNames[i-1] = meta.getColumnName(i);
}
List<Object> rowData = new ArrayList<Object>();
while (result.next()) {
Object[] row = new Object[columns];
for (int j=0; j<= columns; j++) {
row[j-1] = result.getString(j);
}
rowData.add(row);
}
}
} catch (SQLexception e) {
System.out.println(e);
}
}
and the simple get-method of the class SQLquery:
public List<Object> getRowData() {
return rowData;
}
Apparently, your getRowData() method returns a List<Object> whereas it actually contains arrays. Although this looks strange since you say it always returns a list of arrays, I'll assume that's what you have.
You need a loop which goes over these "objects", downcasting them to Object[], and taking the first member.
Object[] sizes = new Object[sizeList.size()];
int i = 0;
for (Object o : sizeList) sizes[i++] = ((Object[]) o)[0];
return sizes;
You could use the approach what Marko Topolnik suggested.
However I would suggest to write your own "Table" class, which parses the result set and puts the values into an N*M dimensional array (or List) depending on your query. This way you can store meta information like the size of N or M dimension, etc.
Related
So I'm trying to go through an arraylist of objects that all have a certain strength value and depending on their strength value, they go into the bigger 2d array based on that. So if their strength value is 0 then they go in the 0th array of the bigger one and this is what my code looks like so far
private ArrayList<Battleable> arr;
public BattleDeck() {
arr = new ArrayList<Battleable>();
for (Battleable creature: arr){
arr.add(creature);
}
}
public Battleable[][] export2Darray() {
//returns a two-dimensional ragged array where each row
// contains a deep copy of all of the Battleable objects
// in the BattleStack with the corresponding Level value
Battleable[][] retVal = new Battleable[10][];
int k = 0;
for (int i = 0; i<arr.size(); i++){
int levelOfObj = arr.get(i).getLevel();
if(levelOfObj == k) {
//insert it into retVal[0][0]
}
}
}
return retVal;
}
and I was wondering how I would do that? How do i syntax-tically say "get the obj that has strength 0 and put it in position 0 0 of my 2d array
A solution using Java 8 streams:
// group Battleables ArrayList by strength
Map<Integer, List<Battleable>> map =
arr.stream().collect(Collectors.groupingBy(Battleable::getStrength));
The result is a Map containing the Battleables as Lists with their strength as their key.
If you need the result as a jagged 2D array, sort the entries like this:
final Battleable[][] arrays = new Battleable[10][];
map.entrySet().forEach(entry -> {
arrays[entry.getKey()] = entry.getValue().toArray(new Battleable[entry.getValue().size()]);
});
Since arrays are of fixed size in Java, there is no clean way to add items to an array. You can resize the array each time by creating a new array each time, one larger than the last, and copying the data from the old array to the new array, but that would be messy and you would be reinventing a wheel called ArrayList. Modus Tollens has a good answer, but it uses some slightly advanced Java 8 concepts. Here's one way to write it without them:
public Battleable[][] export2Darray() {
Battleable[][] retVal = new Battleable[10][];
// create a map that will hold the items, arranged by level
Map<Integer, List<Battleable>> byLevel = new HashMap<>();
for (int i = 0; i < 10; i++) {
// initialize all levels with empty lists
byLevel.put(i, new ArrayList<>());
}
for (Battleable battleable : arr) {
int level = battleable.getLevel();
// get the list for this level and add to it
byLevel.get(level).add(battleable);
}
// Now we have a map from levels to lists of battleables;
// we need to turn each list into an array in our retVal
for (int level = 0; level < 10; level++) {
// get each list, convert it toArray and assign to slot in retVal
retVal[level] = byLevel.get(level).toArray(new Battleable[0]);
}
return retVal;
}
Here's a solution using ArrayLists, I am creating an ArrayList which will be referenced by strength, then inside of this I have another ArrayListwhich will have all of the Battleable objects of that strength level.
public ArrayList<ArrayList<Battleable>> exportBattleable() {
ArrayList<ArrayList<Battleable>> retVal = new ArrayList<ArrayList<Battleable>>();
for (int i = 0; i < arr.size(); i++){
retVal.get(arr.getLevel()).add(arr.get(i));
}
return retVal;
}
Now if you want to print all Battleable objects of strength = 3, you would do:
ArrayList<Battleable> strength3 = retVal.get(3);
for(Battleable battleable : strength3) {
System.out.println(battleable.toString());
}
This way you don't have to worry about re-sizing your arrays depending on how many Battleable objects you are adding in, same with strength levels, if you decide that instead of using strength levels from 0-9 that you wanted to use 0-20 you already have the ability to scale up or down.
array=[]
sent to servlet >>>>
///////// how i get [0]-[3] in array value in array [0-50]
for(????)
{ var A = get[0].toString;
var b = get[1].toString;
var c = get[2].toString;
var d = get[3].toString;
}
You can use Lists class from Guava
Object[] array = new Objects[50];
//... somehow fill array with real data
List<List<Object>> parts = Lists.partition(Arrays.asList(array), 4);
for(List<Object> part: parts){ //List 'part' will always contain not more than 4 elements
proccessPart(part); //passing elements to the method wich interacts with database
}
With the limited given information, If the question is how to processs an array which contains 50 objects with 4 untouched continuous objects sequentially
Object[] array = new Object[50];
//populate array
for(int i=3;i<50;i+=4) {
Object a = array[i-3];
Object b = array[i-2];
Object c = array[i-1];
Object d = array[i];
//variables may not be required as you can directly use array[i]
}
I have a .csv file of type:
Event Participant
ConferenceA John
ConferenceA Joe
ConferenceA Mary
ConferenceB John
ConferenceB Ted
ConferenceC Jessica
I would like to create a 2D boolean matrix of the following format:
Event John Joe Mary Ted Jessica
ConferenceA 1 1 1 0 0
ConferenceB 1 0 0 1 0
ConferenceC 0 0 0 0 1
I start by reading in the csv and using it to initialize an ArrayList of type:
AttendaceRecord(String title, String employee)
How can I iterate through this ArrayList to create a boolean matrix like the one above in Java?
This is the easiest way I can think of for you. This answer can certainly be improved or done in a completely different way. I'm taking this approach because you mentioned that you are not completely familiar with Map (I'm also guessing with Set). Anyway let's dive in.
In your AttendanceRecord class you are going to need the following instance variables: two LinkedHashSet and one LinkedHashMap. LinkedHashSet #1 will store all conferences and LinkedHashSet #2 will store all participants. The LinkedHashMap will store the the conferences as keys and participants list as values. The reason for this will be clear in a minute. I'll first explain why you need the LinkedHashSet.
Purpose of LinkedHashSet
Notice in your 2d array, the rows (conferences) and columns (participants) are arranged in the order they were read. Not only that, all duplicates read from the file are gone. To preserve the ordering and eliminate duplicates a LinkedHashSet fits this purpose perfectly. Then, we will have a one-to-one relationship between the row positions and the column positions of the 2d array and each LinkedHashSet via their array representation. Let's use Jhon from ConferenceA for example. Jhon will be at position 0 in the array representation of the participant Set and ConferenceA will be at position 0 in the array representation of the conference Set. Not only that, the size of each array will be used to determine the size of your 2d array (2darray[conferenceArrayLength][participantArrayLength])
Purpose of the LinkedHashMap
We need the LinkedHashMap to preserve the ordering of the elements (hence Linked). The elements will be stored internally like this.
ConferenceA :Jhon Joe Mary
ConferenceB :Jhon Ted
ConferenceC :Jessica
We will then iterate through the data structure and send each key value pair to a function which returns the position of each element from each array returned from each LinkedHashSet. As each row and column position is returned, we will add a 1 to that position in the 2d array.
Note: I used an Integer array for my example, substitute as needed.
AttendanceRecord.java
public class AttendanceRecord {
private Map<String, ArrayList> attendanceRecordMap = new LinkedHashMap<String, ArrayList>();
private Set<String> participants = new LinkedHashSet<String>();
private Set<String> conferences = new LinkedHashSet<String>();
public AttendanceRecord() {
}
public Map<String, ArrayList> getAttendanceRecordMap() {
return attendanceRecordMap;
}
public Object[] getParticipantsArray() {
return participants.toArray();
}
public Object[] getConferencesArray() {
return conferences.toArray();
}
public void addToRecord(String title, String employee) {
conferences.add(title);
participants.add(employee);
if (attendanceRecordMap.containsKey(title)) {
ArrayList<String> tempList = attendanceRecordMap.get(title);
tempList.add(employee);
} else {
ArrayList<String> attendees = new ArrayList<String>();
attendees.add(employee);
attendanceRecordMap.put(title, attendees);
}
}
}
Test.java
public class Test {
public static void main(String[] args) {
AttendanceRecord attendanceRecord = new AttendanceRecord();
//There are hardcoded. You will have to substitute with your code
//when you read the file
attendanceRecord.addToRecord("ConferenceA", "Jhon");
attendanceRecord.addToRecord("ConferenceA", "Joe");
attendanceRecord.addToRecord("ConferenceA", "Mary");
attendanceRecord.addToRecord("ConferenceB", "Jhon");
attendanceRecord.addToRecord("ConferenceB", "Ted");
attendanceRecord.addToRecord("ConferenceC", "Jessica");
int[][] jaccardArray = new int[attendanceRecord.getConferencesArray().length][attendanceRecord.getParticipantsArray().length];
setUp2dArray(jaccardArray, attendanceRecord);
print2dArray(jaccardArray);
}
public static void setUp2dArray(int[][] jaccardArray, AttendanceRecord record) {
Map<String, ArrayList> recordMap = record.getAttendanceRecordMap();
for (String key : recordMap.keySet()) {
ArrayList<String> attendees = recordMap.get(key);
for (String attendee : attendees) {
int row = findConferencePosition(key, record.getConferencesArray());
int column = findParticipantPosition(attendee, record.getParticipantsArray());
System.out.println("Row inside " + row + "Col inside " + column);
jaccardArray[row][column] = 1;
}
}
}
public static void print2dArray(int[][] jaccardArray) {
for (int i = 0; i < jaccardArray.length; i++) {
for (int j = 0; j < jaccardArray[i].length; j++) {
System.out.print(jaccardArray[i][j]);
}
System.out.println();
}
}
public static int findParticipantPosition(String employee, Object[] participantArray) {
int position = -1;
for (int i = 0; i < participantArray.length; i++) {
if (employee.equals(participantArray[i].toString())) {
position = i;
break;
}
}
return position;
}
public static int findConferencePosition(String employee, Object[] conferenceArray) {
int position = -1;
for (int i = 0; i < conferenceArray.length; i++) {
if (employee.equals(conferenceArray[i])) {
position = i;
break;
}
}
return position;
}
}
Basically you'll want to start by searching through your input strings to find each of the names (String.contains) and set a boolean array of each field name.
Then you'll make an array of those boolean arrays (or a list, whatever).
Then you simply sort through them, looking for T/F and printing corresponding messages.
I included some very rough pseudocode, assuming I am understanding your problem correctly.
// For first row
List labelStrings[];
labelStrings = {"Event", "John", "Joe", "Mary", "Ted", "Jessica"};
// For the matrix data
// List to iterate horizontally EDIT: Made boolean!
List<Boolean> strList= new ArrayList()<List>;
// List to iterate vertically
List<List> = listList new ArrayList()<List>;
/* for all the entries in AttendanceRecord (watch your spelling, OP)
for all data sets mapping title to employee
add the row data to strList[entry_num] */
for (int i = 0; i < listList.size()-1; i++)
for (int j = 0; j < labelStrings.size()-1; j++)
{
if (i == 0)
System.out.println(strList[j] + "\t\n\n");
else
{
// print listLists[i][j]
}
// iterate row by row (for each horizontal entry in the column of entries)
}
Sorry, I'm just reading through the comments now.
You'll definitely want to arrange your data in a way that is easy to iterate through. Since you have a fixed table size, you could hardcode a boolean array for each entry and then print on validation they were mapped to the event as indicated in your input string.
Try creating a hash map containing
HashMap map = new HashMap<conferenceStr, HashMap<nameStr, int>>()
As you iterate through your ArrayList, you can do something like
innerMap = map.get(conferenceStr)
innerMap.put(nameStr, 1)
of course you'll need some initialization logic, like you can check if innerMap.get(nameStr) exists, if not, iterate over every inner map and innerMap.put(nameStr, 0)
This structure can be used to generate that final 2D boolean matrix.
Elaboration edit:
ArrayList<AttendanceRecord> attendanceList = new ArrayList<AttendanceRecord>();
// populate list with info from the csv (you implied you can do this)
HashMap<String, HashMap<String, Integer>> map = new HashMap<String, HashMap<String, Integer>>();
//map to store every participant, this seems inefficient though
HashMap<String, Integer>> participantMap = new HashMap<String, Integer>();
for (AttendanceRecord record : attendanceList) {
String title = record.getTitle();
String employee = record.getEmployee();
participantMap.put(employee, 0);
HashMap<String, Integer> innerMap = map.get(title);
if (innerMap == null) {
innerMap = new HashMap<String, Integer>();
}
innerMap.put(employee, 1);
}
//now we have all the data we need, it's just about how you want to format it
for example if you wanted to just print out a table like that you could iterate through every element of map doing this:
for (HashMap<String, Integer> innerMap : map.values()) {
for (String employee : participantMap.values()) {
if (innerMap.get(employee)) {
//print 1
}
else
//print 0
}
}
I have 3 arraylist each have size = 3 and 3 arrays also have length = 3 of each. I want to copy data from arraylists to arrays in following way but using any loop (i.e for OR for each).
myArray1[1] = arraylist1.get(1);
myArray1[2] = arraylist2.get(1);
myArray1[3] = arraylist3.get(1);
I have done it manually one by one without using any loop, but code appears to be massive because in future I'm sure that number of my arraylists and arrays will increase up to 15.
I want to copy the data from arraylists to arrays as shown in the image but using the loops not manually one by one?
How about this?
List<Integer> arraylist0 = Arrays.asList(2,4,3);
List<Integer> arraylist1 = Arrays.asList(2,5,7);
List<Integer> arraylist2 = Arrays.asList(6,3,7);
List<List<Integer>> arraylistList = Arrays.asList(arraylist0, arraylist1, arraylist2);
int size = 3;
int[] myArray0 = new int[size];
int[] myArray1 = new int[size];
int[] myArray2 = new int[size];
int[][] myBigArray = new int[][] {myArray0, myArray1, myArray2};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
myBigArray[i][j] = arraylistList.get(j).get(i);
}
}
To explain, since we want to be able to work with an arbitrary size (3, 15, or more), we are dealing with 2-dimensional data.
We are also dealing with array and List, which are slightly different in their use.
The input to your problem is List<Integer>, and so we make a List<List<Integer>> in order to deal with all the input data easily.
Similarly, the output will be arrays, so we make a 2-dimensional array (int[][]) in order to write the data easily.
Then it's simply a matter of iterating over the data in 2 nested for loops. Notice that this line reverses the order of i and j in order to splice the data the way you intend.
myBigArray[i][j] = arraylistList.get(j).get(i);
And then you can print your answer like this:
System.out.println(Arrays.toString(myArray0));
System.out.println(Arrays.toString(myArray1));
System.out.println(Arrays.toString(myArray2));
You need to have two additional structures:
int[][] destination = new int [][] {myArray1, myArray2,myArray3 }
List<Integer>[] source;
source = new List<Integer>[] {arraylist1,arraylist2,arraylist3}
myArray1[1] = arraylist1.get(1);
myArray1[2] = arraylist2.get(1);
myArray1[3] = arraylist3.get(1);
for (int i=0;i<destination.length;i++) {
for (int j=0;j<source.length;j++) {
destination[i][j] = source[j].get(i);
}
}
If you cannot find a ready made API or function for this, I would suggest trivializing the conversion from List to Array using the List.toArray() method and focus on converting/transforming the given set of lists to a another bunch of lists which contain the desired output. Following is a code sample which I would think achieves this. It does assume the input lists are NOT of fixed/same sizes. Assuming this would only make the logic easier.
On return of this function, all you need to do is to iterate over the TreeMap and convert the values to arrays using List.toArray().
public static TreeMap<Integer, List<Integer>> transorm(
List<Integer>... lists) {
// Return a blank TreeMap if not input. TreeMap explanation below.
if (lists == null || lists.length == 0)
return new TreeMap<>();
// Get Iterators for the input lists
List<Iterator<Integer>> iterators = new ArrayList<>();
for (List<Integer> list : lists) {
iterators.add(list.iterator());
}
// Initialize Return. We return a TreeMap, where the key indicates which
// position's integer values are present in the list which is the value
// of this key. Converting the lists to arrays is trivial using the
// List.toArray() method.
TreeMap<Integer, List<Integer>> transformedLists = new TreeMap<>();
// Variable maintaining the position for which values are being
// collected. See below.
int currPosition = 0;
// Variable which keeps track of the index of the iterator currently
// driving the iteration and the driving iterator.
int driverItrIndex = 0;
Iterator<Integer> driverItr = lists[driverItrIndex].iterator();
// Actual code that does the transformation.
while (driverItrIndex < iterators.size()) {
// Move to next driving iterator
if (!driverItr.hasNext()) {
driverItrIndex++;
driverItr = iterators.get(driverItrIndex);
continue;
}
// Construct Transformed List
ArrayList<Integer> transformedList = new ArrayList<>();
for (Iterator<Integer> iterator : iterators) {
if (iterator.hasNext()) {
transformedList.add(iterator.next());
}
}
// Add to return
transformedLists.put(currPosition, transformedList);
}
// Return Value
return transformedLists;
}
In my application I need to have a 2 dimensional array. If I define it fix it works fine, like this:
static final String arrGroupelements[] = {"India", "Australia", "England", "South Africa"};
static final String arrChildelements[][] = { {"Sachin Tendulkar", "Raina", "Dhoni", "Yuvi" },
{"Ponting", "Adam Gilchrist", "Michael Clarke"},
{"Andrew Strauss", "kevin Peterson", "Nasser Hussain"},
{"Graeme Smith", "AB de villiers", "Jacques Kallis"} };
However, in my code I have two lists. the first is list of recipe name that i can get it.
LinkedList<String> recipeList = dbShoppingHandler.getAllRecipeNames();
String arrGroupelements[] = new String[recipeList.size()];
for(int i=0; i<recipeList.size(); i++) {
arrGroupelements[i] = recipeList.get(i);
}
My second list is list of ingredients. In order to get list of ingredients i need to set recipe name and then i can get the list. However, i don't know how put this list as second dimension. my code is like this:
String arrChildelements[][] = new String[recipeList.size()][20];
for(int i=0; i<recipeList.size(); i++) {
LinkedList<String> ingredient = dbShoppingHandler.getIngredientsOfRecipeName(recipeList.get(i));
for(int j=0; j<ingredient.size(); j++) {
arrChildelements[i][j] = ingredient.get(j);
}
}
Bad thing is, i need to set a number (in my case 20) for second dimension. If i do like this for lists that have 5 items i will have 15 " " elements and those have more than 20 items the code ignore them.
First dimension is fix but i need to adjust second dimension based on number of ingredients.
any suggestion are appreciated. thanks.
How about assigning an array in the desired sise:
String arrChildelements[][] = new String[recipeList.size()][];
// not mentioning second dimension size ^^
for(int i=0; i<recipeList.size(); i++) {
LinkedList<String> ingredient = dbShoppingHandler.getIngredientsOfRecipeName(recipeList.get(i));
arrChildelements[i] = String[ingredient.size()];
// assigning new array here ^^
for(int j=0; j<ingredient.size(); j++) {
arrChildelements[i][j] = ingredient.get(j);
}
}
I suggest not to use 2D arrays for dynamic structures. Arrays are immutable, so you have to copy them, create gaps and move elements around. The standard Java library doesn't offer many useful methods to do that.
Instead, use a list of lists:
List<List<String>> data = new ArrayList<List<String>>();
Lists have many useful methods to append elements, insert and remove them and they will make you life much easier.
The simplest way to to not assume you know the length in advance.
String[][] arrChildelements[] = new String[recipeList.size()][];
for(int i=0; i<recipeList.size(); i++) {
List<String> ingredient = dbShoppingHandler.getIngredientsOfRecipeName(recipeList.get(i));
arrChildelements[i] = ingredient.toArray(new String[0]);
}