Situation
Well, this method is managing a conversion which accepts a list as a parameter, but definately doesn't look scalable.
List<Long> array_list_data= new ArrayList<>();
public void get_Data() {
long0 = array_list_data.get(0);
long1= array_list_data.get(1);
long2= array_list_data.get(2);
}
Afterwards, it will create a different class with the long fields.
Problem
However, what if we have to expand this data to a 100 parameters on this list?
What I have done so far is:
List<Long> array_list_data= new ArrayList<>();
public void get_Data() {
int k = 0;
long0= array_list_data.get(k);
long1= array_list_data.get(k++);
long2= array_list_data.get(k++);
}
Why incrementing k is not the right way to do it?
k++ performs a post-increment. In other words, the value of the expression is the original value of k, and then k is incremented. It's still incremented before the method is called, but the value passed as the argument is the value before the increment takes place. In other words, a call of:
x = list.get(k++);
is equivalent to:
int tmp = k;
k = k + 1;
x = list.get(tmp);
So if you actually had:
memory_version = array_list_data.get(k++); // Calls with 0, then k=1
mains_voltage_min = array_list_data.get(k++); // Calls with 1, then k=2
mains_voltage_max = array_list_data.get(k++); // Calls with 2, then k=3
then it would be fine, and equivalent to your first code. Your current problem is that you've actually got:
memory_version = array_list_data.get(k); // Calls with 0, then k=0
mains_voltage_min = array_list_data.get(k++); // Calls with 0, then k=1
mains_voltage_max = array_list_data.get(k++); // Calls with 1, then k=2
However, I'd suggest that if you're modelling the data in a class using a collection as a field, you may well be better off with a separate field for each value. (You may create an instance of the class by extracting the data from a list, of course, but that's a different matter.)
k++ will return the value of k then increment it.
++k will increment k then return the incremented value.
You should use ++k in your situation.
It works fine, just k++ does first return k and then increment it by one, so you get k, k, k+1, k+2, etc. Use ++k instead. Or use k++ in the first call, too, your choice.
Although your approach works fine with some tweaking of ++ position, with 100 fields you may be better off with reflection. Put field names into an array or a list, then go through them one by one in a loop, and set values based on a loop variable:
String[] fieldNames = new String[] {"memory_version", " mains_voltage_min", ...};
...
Class<MyClass> c = MyClass.class;
for (int i = 0 ; i != fieldNames.length ; i++) {
Field f = c.getDeclaredField(fieldNames[i]);
f.setLong(this, array_list_data.get(i));
}
This reduces your list processing code to a few simple lines, and lets you change the order of fields in array_list_data simply by arranging your fieldNames array in proper order.
You don't need to maintain the index variable at all; this is why we have iterators:
final Iterator<Integer> iterator = array_list_data.iterator();
memory_version = iterator.next();
mains_voltage_min = iterator.next();
mains_voltage_max = iterator.next();
To manage scalability, I'd use an enum and a Map:
enum Var {
MEMORY_VERSION(0),
MAINS_VOLTAGE_MIN(1),
MAINS_VOLTAGE_MAX(2);
private Integer value;
Var(Integer value) {
this.value = value;
}
public Integer value() { return value; }
}
List<Long> array_list_data= new ArrayList<>();
Map<Integer, Long> variables = new HashMap<>();
public void getData() {
for (int j=0; j<array_list_data.size(); j++) {
variables.put(j, array_list_data.get(j));
}
}
public void test() {
System.out.println("Memory version: " + variables.get(Var.MEMORY_VERSION.value()));
}
so that you can add as many vars as you need, and you can retrieve with a meaningful name, like in the test() method.
Just about the incrementing part, try this:
public void getData() {
int i = 0;
// get element 0, then increment i
memory_version = array_list_data.get(i++);
// get element 1, then increment i
mains_voltage_min = array_list_data.get(i++);
// get element 2, then increment i
mains_voltage_max = array_list_data.get(i++);
}
That's how I do it for example when working with JDBC ResultSet.
Related
It's basic, but i cant find an answer... I am calling method Kmeans(centers, dataset, k) with 3 parameters in my Main class. The method returns centers. How can I use this return of centers in another class for loop?
From Main class calling method with...
concurrentKmeans(centers, dataset, k);
Method...
public static List<TockaXY> kmeans(List<TockaXY> centers, List<TockaXY> dataset, int k) {
boolean converged;
do {
List<TockaXY> noviCentri = noviCentri(dataset, centers);
double dist = dobiRazdaljoCenters(centers, noviCentri);
centers = noviCentri;
converged = dist == 0;
} while (!converged);
return centers;
}
Trying to use it here in for loop to iterate the List<TockaXY> ...
public class WebviewLoadListner implements ChangeListener<State>{
#Override
public void changed(ObservableValue<? extends State> observable, State from, State to) {
if (to == State.SUCCEEDED)
{
SampleController.engine.executeScript("jumpTo("+46.641389+","+49.756667+","+10+")");
for(int i =0; i<Main.kmeans(centers, dataset, k); i++){
}
}
}
}
The better way is to call the method and set it to a local variable and then use it in the for loop. It is not ideal to use the function call inside the for loop condition, since each time it is evaluated and the same function will be called for each loop iteration, which will impact the performance.
SampleController.engine.executeScript("jumpTo("+46.641389+","+49.756667+","+10+")");
List<TockaXY> list = Main.kmeans(centers, dataset, k);
for(int i =0; i< list.size(); i++){
//Use list.get(i) for each individual element in the list
}
or
List<TockaXY> list = Main.kmeans(centers, dataset, k);
for(TockaXY toc : list) {
//toc will give individual element in the list
}
With JDK 8, we can use streams to access elements
List<TockaXY> list = Main.kmeans(centers, dataset, k);
list.stream().forEach(toc -> {
//Your operation with toc
});
In your for loop you are comparing two different types int and List<TockaXY>. I think you mean to use the List's size().
i<Main.kmeans(centers, dataset, k).size(); instead of i<Main.kmeans(centers, dataset, k);
I'm trying to replace the below code using stream API, Optional API. I'm unable to think of a solution. Kindly help me on this.
Note: Please don't bother with the FUNCTIONALITY. This is not the exact client code and hence some of the operations doesn't make sense from the outside perspective.
public class Person {
private String fName;
private String lName;
private String empId;
// constructors, setters, getters
}
.. MAIN CLASS..
private boolean indexExists(final List <Person> list, final int index) {
return index >= 0 && index < list.size();
}
public void mainFunction() {
Person per1 = new Person("fname1", "lname1", "101");
Person per2 = new Person("fname2", "lname2", "102");
List<Person> allPersons = new ArrayList<>();
allPersons.add(per1);
allPersons.add(per2);
System.out.println(allPersons);
List<String> lNamesAppend = Arrays.asList("123","456","789");
// CAN THE BELOW BE REPLACED IN JAVA8 ?
int index = 0;
Person person = null;
for(String str : lNamesAppend) {
if(indexExists(allPersons, index)) {
person = allPersons.get(index++);
} else {
person = new Person("fname" + index++ , "lname" + index++, "10" + index++);
allPersons.add(person);
}
person.setlName(str + index);
}
System.out.println(allPersons);
}
You can create code using the Stream API following the same logic, but there is no sense in doing that without revising the logic. After all, the Stream API allows you to express the intent instead of an iteration logic, at least when you have a suitable task. If not suitable, there is no advantage in changing the code.
In your case, the logic is flawed right from the start, as you are polling indices for validity, despite you know in advance that the valid indices of a list form a range from zero to the list’s size, just to do two entirely different operations, updating old entries or creating new entries, within the same loop.
Compare with a straight-forward approach not doing two things in one:
int existing = Math.min(allPersons.size(), lNamesAppend.size());
for(int index = 0; index < existing; index++)
allPersons.get(index).setlName(lNamesAppend.get(index)+index);
for(int index = existing, end = lNamesAppend.size(); index < end; index++)
allPersons.add(new Person("fname"+index, lNamesAppend.get(index)+index, "10"+index));
I assumed doing index++ three times for a new Person was a bug.
You can do the same using the Stream API:
int existing = Math.min(allPersons.size(), lNamesAppend.size());
IntStream.range(0, existing)
.forEach(index -> allPersons.get(index).setlName(lNamesAppend.get(index)+index));
allPersons.addAll(IntStream.range(existing, lNamesAppend.size())
.mapToObj(index -> new Person("fname"+index,lNamesAppend.get(index)+index,"10"+index))
.collect(Collectors.toList()));
Following is one of the options. Note that the code is not CLEAN, given that the functionality isn't clear, but you can get an idea on how to achieve it
//mainMethod
{
....
AtomicInteger index = new AtomicInteger();
lNamesAppend.stream()
.map(str-> indexExists(allPersons, index.get()) ?
new ImmutablePair<>(str, allPersons.get(index.getAndIncrement())) :
new ImmutablePair<>(str, getPerson(allPersons, index)))
.forEach(p->p.getRight().setlName(p.getLeft()+index));
}
private Person getPerson(List<Person> allPersons, AtomicInteger index) {
Person person = new Person("fname" + index.getAndIncrement(), "lname" + index.getAndIncrement(), "10" + index.getAndIncrement());
allPersons.add(person);
return person;
}
Hi community I have a question, I happen to have an array of objects loaded on startup, through that generate array another array of integers that contains your code, it appears that array of integers'm removing their values, what I want is to compare the list of integer array currently have with the array of objects, and remove all code object that whole array mentioned is found.
My code java:
private List<ValidColumnKey> columnCustomer;
private int[] selectedCustomer;
public void init(){
this.setColumnCustomer(new ArrayList<ValidColumnKey>());
this.getColumnCustomer().add(new ValidColumnKey(1, "Codigo", "code"));
this.getColumnCustomer().add(new ValidColumnKey(2, "Nombre", "name"));
this.getColumnCustomer().add(new ValidColumnKey(3, "Nombre Comercial", "comercialName"));
this.getColumnCustomer().add(new ValidColumnKey(4, "Estado", "isActive"));
this.setSelectedCustomer(new int [this.getColumnCustomer().size()]);
int i = 0;
for(ValidColumnKey column : this.getColumnCustomer()){
this.getSelectedCustomer()[i] = column.getCodigo();
i++;
}
}
I mean I would have my array of integers with codes removed, like this:
selectedCustomer = [1, 2, 3];
What I wanted was to remove from the list of objects that do not have codes in the array of integers, but it is not my code:
List<ValidColumnKey> auxRemoColumnKeys = new ArrayList<ValidColumnKey>();
for(ValidColumnKey column : this.getColumnCustomer()){
for(Integer codigo : this.getSelectedCustomer()){
if (column.getCodigo() != codigo) {
auxRemoColumnKeys.add(column);
break;
}
}
}
this.getColumnCustomer().remove(auxRemoColumnKeys);
I could guide the solution.
this.getColumnCustomer().remove(auxRemoColumnKeys);
This statement assumes you have a valid equals method for your class ValidColumnKey, which I suspect is probably not the case.
What you want to do is iterate with a Iterator. Some sample code could be like
Set<Integer> toRemoveCodes = new HashSet<Integer>(Arrays.asList(1, 2, 3));
for (Iterator<ValidColumnKey> it = this.getColumnCustomer().iterator(); it.hasNext(); ) {
ValidColumnKey curColumnKey = it.next();
Integer code = curColumnKey.codigo();
if (toRemoveCodes.contains(code)) {
it.remove();
}
}
There are multiple reasons your current attempt is failing. The first is that this line:
if (column.getCodigo() != codigo) {
Is testing for object equivalence between Integers, not value equavalence between ints. If you want to compare Integers, you have to use the equals method:
if (!column.getCodigo().equals(codigo)) {
However, if getCodigo returns an int and getSelectedCustomer returns an int[] then this line should be changed instead:
for(int codigo : this.getSelectedCustomer()){
Because you didn't need to use Integer in the first place.
Secondly, this line attempts to remove auxRemoColumnKeys itself so you probably mean removeAll:
this.getColumnCustomer().remove(auxRemoColumnKeys);
Lastly, your logic is generally flawed. It basically says "for each element in getColumnCustomer, if getCodigo is not equal to all of getSelectedCustomer remove it". I don't think that's what you've intended.
This is a modified loop that uses the same "add to a list and remove the list items" procedure but the logic will work:
List<ValidColumnKey> auxRemoColumnKeys = new ArrayList<ValidColumnKey>();
int[] selected = this.getSelectedCustomer();
for (ValidColumnKey column : this.getColumnCustomer()) {
int i = 0;
for ( ; i < selected.length; i++) {
/* note: if getCodigo returns an Integer change this check to
* "if (column.getCodigo().equals(selected[i])) {"
*/
if (column.getCodigo() == selected[i]) {
break;
}
}
/* this says "if the search loop did not break early" */
if (i == selected.length) {
auxRemoColumnKeys.add(column);
}
}
this.getColumnCustomer().removeAll(auxRemoColumnKeys);
I have a list like this
List contains set of dtime,uptime values.I want to get the list items i.e., dtime into one and
uptime into another variable.Likewise I want to get all the dtime and uptime pair values seperatly into
the variables using for loop in java.How can I achieve this.Is it possible list or vector?Please help me.
Pseudo code
List.get(0).get(0)-->gives 1st dtime
List.get(0).get(1)-->gives 1st uptime
List.get(1).get(0)-->gives 2nd dtime
List.get(1).get(1)-->gives 2nd uptime
And so on..
How to implement this with for loop I am not getting.I am new to java>please help me..
First Convert That ArrayList into Object[] array then get the value like given below code...driver_ModelsObj is an array convert that into drives object array then get the value from inside the array.
for(int indx=0;indx<driver_ModelsObj.size();indx++){
Object[] drivers=(Object[]) driver_ModelsObj.get(indx);
String Device_ID=drivers[0].toString();
}
If your list is as below
List list = [[1],[2],[3]];
We can retrieve the each value as below.
((List)list.get(0)).get(0); //This will retrieve value 1
((List)list.get(1)).get(0); //This will retrieve value 2
Sounds like you could use a domain object containing uptime and downtime.
For example,
public class Stats {
int dtime;
int uptime;
}
Then you can have a List<Stats> and access it like this:
mylist.get(0).dtime
mylist.get(0).uptime
mylist.get(1).dtime
mylist.get(1).uptime
Part of the (newer) Collcetions framework, List is almost always a better alternative than Vector
List.get(0).get(0)-->gives 1st dtime
List.get(0).get(1)-->gives 1st uptime
Well, what you're doing here, is getting the list at position 0, and getting item 1 from that list. In a for loop we can express this as:
for(int x = 0; x < List.size(); x++)
{
for(int y = 0; y < List.get(x).size(); y++)
{
if(y % 2 == 0)
{
// It's a dtime object.
}
else
{
// It's an uptime object.
}
}
}
Before this, you could declare some lists of your own:
List<DTime> listD = new ArrayList<ATimeObject>();
List<UpTime> listUp = new ArrayList<UpTime>();
Now when you're cycling through, all you need to do is add the relevant object:
if(y % 2 == 0)
{
listD.add(List.get(x).get(y));
}
else
{
listUp.add(List.get(x).get(y));
}
You should create a POJO like
public class TimeData {
double dtime;
Date uptime;
}
Then add each POJO to array list and then iterate it.
List<TimeData> oList = new ArrayList<TimeData>();
int nSize = oList.size();
for(int i=0;i<nSize;i++){
TimeData child = oList.get(i);
// get value using getters
}
You can try this ,Let say you have variables like
double dtime;
Timestamp tp;
And listofresults is coming from query results.
listofresults = results.getResultList();
If list is coming from query then put it in the loop this way in the condition of for loop
for(int i=0;i< listofresults.size() ;i=i+2)
{
dtime=(double) listofresults.get(i);
//cast because the value is of object type
tp=(TimeStamp) listofresults.get(i+1);
//cast because the value is of object type
//do something with these variables
}
I recommend creating a wrapper for it.
public class UpTimeDownTime {
MyTimeDataClass downtime;
MyTimeDataClass uptime;
public UpTimeDownTime(MyTimeDataClass downtime, MyTimeDataClass uptime){
this.downtime = downtime;
this.uptime = uptime;
}
public MyTimeDataClass getDowntime () {
return downtime;
}
public MyTimeDataClass getUptime () {
return uptime;
}
public static void main (String[] args) {
List<List<MyTimeDataClass>> List = ...;
List<UpTimeDownTime> uptimeDowntime = new ArrayList<UpTimeDownTime>();
for(List<MyTimeDataClass> timeList : List){
UpTimeDownTime u = new UpTimeDownTime(timeList.get(0), timeList.get(1));
uptimeDowntime.add(u);
}
}
}
I've got an array of int's. I need to add 1 to each of its elements. What's the shortest, most general way to add a given constant to each element, that is, without explicit loops? I've looked online and keep getting pages about adding an element onto an array (i.e., concatenation).
Isn't there something more elegant than looping through each element and adding the constant? Is there some sort of standard library method?
For that matter, how would one add two arrays together (i.e., matrix addition) without an explicit loop?
Here is how you can write the two cases above with Functional Java.
1. Adding 1 to each element:
It's a functional programming library, and so it does not provide mutating operations. But you can easily add them yourself.
public static <A> void transform(Array<A> xs, F<A, A> f) {
for(int i = 0; i < xs.length(); i++) {
xs.set(i, f.f(xs.get(i)));
}
}
Use:
transform(yourArray, Integers.add.f(1));
2. Adding two matrices:
Let xss and yss be two matrices, both of types Array<Array<Integer>>. Then you can add them with:
xss.zip(yss).map(new F<P2<Array<Integer>, Array<Integer>>, Array<Integer>>() {
public Array<Integer> f(P2<Array<Integer>, Array<Integer>> p) {
Array<Integer> xs = p._1();
Array<Integer> ys = p._2();
return xs.zip(ys).map(new F<P2<Integer, Integer>, Integer>() {
public Integer f(P2<Integer, Integer> q) {
return q._1() + q._2();
}
});
}
});
This may feel more verbose than necessary, and that is because Java does not support lambda expressions yet. In the meantime, IDEs can help make such techniques more approachable.
If an unmodifiable result is ok, and you're not stuck to using arrays, you could use a cute trick to delay the addition until the last possible moment. But as soon as you need to visit the whole result array, any performance benefit is lost and the code ends up being more complicated than necessary.
public class OffsetArrayList extends AbstractList< Integer > {
private final List< Integer > liUnderlying;
private final int iOffset;
public OffsetArrayList( int iOffset, liUnderlying ) {
this.iOffset = iOffset;
this.liUnderlying = liUnderlying;
}
#Override
public Integer get( int iIndex ) {
return liUnderlying.get( iIndex ) + iOffset;
}
#Override
public Integer set( int iIndex, Integer iNewValue ) {
return liUnderlying.set( iIndex, iNewValue - iOffset ) + iOffset;
}
// etc.
}
// create new array
int[] aiInput = new int[] { 23, 98, -45 };
// two object allocations, but no new array created and no additions performed
OffsetArrayList alPlusOne = new OffsetArrayList( 1, Arrays.asList( aiInput ) );
// one addition performed; constant time
assert( alPlusOne.get( 0 ) == 24 );
// benefit murky, as we are adding to the same element repeatedly
for ( int i = 0; i < 1000000; ++i )
assert( alPlusOne.get( 2 ) == -44 );
// benefit lost, input destroyed
int[] aiOutput = alPlusOne.toArray( aiInput );